pic3.jpeg

Project No Sql¶

Dogs & Cats database¶

Julio Cortes

2025

pic2.jpg Image generated with Chatgpt

Table of Contents¶

  1. Project NoSQL
  2. Dogs & Cats Database
  3. API & NoSQL Project: Cat and Dog Data
    • Key Concepts
    • Outcome
    • Dog Data Extraction Overview
  4. NoSQL Schema Description – Pets DB
    • Structure Overview
    • Why This Design?
  5. Collections Creations
    • Fixing Inconsistencies in life_span Values
  6. Transformation
    • Adding Geo Coordinates to type_dogs & type_cats
    • Action
    • Source of Extracting Geo Coordinates
    • How It's Done
    • Extracting origin from type_cats and adding coordinates
    • Selected Columns Overview
  7. Data Analysis
    • Dogs Database Collection
    • Intelligent Dog Breeds in the Sporting Group
      • Pipeline Breakdown
      • Output
    • Filtered List of Intelligent Sporting Breeds
      • Pipeline Breakdown
      • Output
    • Top 10 Tallest Dog Breeds
      • Pipeline Breakdown
      • Output
    • Average Metric Weight by Dog Breed
      • Pipeline Breakdown
    • Longevity Analysis of Dog Breeds
      • Pipeline Breakdown
      • Result
    • Breed Group Distribution
      • Pipeline Steps
      • Result
    • Cat Breeds by Geographic Origin
      • Steps Involved
      • Outcome
    • Origin Distribution of Cat Breeds
      • Pipeline Breakdown
      • Result
    • Top 10 Longest-Living Cat and Dog Breeds
  8. Conclusion
  9. Learning

🐾 API & NoSQL Project: Cat and Dog Data¶

This beginner-friendly project connects to a public API to collect data on cats and dogs, including:

  • 🐶 Breed names
  • 🧠 Temperament traits
  • 🧬 Other characteristics

The data is stored in a MongoDB NoSQL database.

šŸ’” Key Concepts¶

  • API requests and JSON handling
  • NoSQL data modeling with MongoDB
  • Aggregation and querying unstructured data

šŸš€ Outcome¶

Build a solid foundation in API integration and NoSQL storage, essential for backend and data-driven applications.

Requirements & Configuration

InĀ [27]:
import pymongo
import pprint as pp
import pandas as pd
import requests
import json
import time
import string
import re
import matplotlib.pyplot as plt
import numpy as np
InĀ [28]:
# API and Database details
API_URL_1 = "https://api.thedogapi.com/v1/breeds"
API_URL_2 = "https://api.thecatapi.com/v1/breeds"
DOG_API_KEY = "live_zxfLgASbdmoVWuJ3PZSm5dUrrsuoaJMV0YnoCVlporMq4ijHVnQpkiZQXegC8BYv"  
CAT_API_KEY = "live_MEzvYHLqnt7f6Wi1URvxHttSq8MFuh2s0fLZTAVsqJ1IGZRA0R8eUknafoFDm0Xc"  
CNX_STR = "localhost:27017"
DB_NAME_1 = "dogsdb"
DB_NAME_2 = "catsdb"
DB_NAME_3 = "petsdb"
COLL_NAME_1 = "type_dogs"
COLL_NAME_2 = "type_cats"
COLL_NAME_3 = "type_pets"

ELT Process DB Setup

InĀ [29]:
# connection to MongoDB
client = pymongo.MongoClient(CNX_STR)
#dogs database 
db_1 = client[DB_NAME_1]
dogs = db_1[COLL_NAME_1]

#cats databse
db_2 = client[DB_NAME_2]
cats = db_2[COLL_NAME_2]

#Pets Database
db_3 = client[DB_NAME_3]
pets = db_3[COLL_NAME_3]
InĀ [30]:
# Remove all existing collection 
cats.drop()
dogs.drop()
pets.drop()

client.drop_database("petsdb")
client.drop_database("catsdb")
client.drop_database("dog_database")
client.drop_database("cat_database")

Extract & find a document

InĀ [31]:
# download all dog breeds 
url = f'{API_URL_1}?f='
headers = {"x-api-key": DOG_API_KEY}
response = requests.get(url, headers=0)
dog = response.json()
InĀ [32]:
# inspect first dog
sample_dog = dog[0]  # This accesses the first element in the list.
pp.pprint(sample_dog)
{'bred_for': 'Small rodent hunting, lapdog',
 'breed_group': 'Toy',
 'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
 'id': 1,
 'life_span': '10 - 12 years',
 'name': 'Affenpinscher',
 'origin': 'Germany, France',
 'reference_image_id': 'BJa4kxc4X',
 'temperament': 'Stubborn, Curious, Playful, Adventurous, Active, Fun-loving',
 'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
InĀ [33]:
# download all cat breeds 
url = f'{API_URL_2}?f='
headers = {"x-api-key": CAT_API_KEY}
response = requests.get(url, headers=0)
cat = response.json()
InĀ [34]:
# inspect first cat
sample_cat = cat[0]  # This accesses the first element in the list.
pp.pprint(sample_cat)
{'adaptability': 5,
 'affection_level': 5,
 'alt_names': '',
 'cfa_url': 'http://cfa.org/Breeds/BreedsAB/Abyssinian.aspx',
 'child_friendly': 3,
 'country_code': 'EG',
 'country_codes': 'EG',
 'description': 'The Abyssinian is easy to care for, and a joy to have in your '
                'home. They’re affectionate cats and love both people and '
                'other animals.',
 'dog_friendly': 4,
 'energy_level': 5,
 'experimental': 0,
 'grooming': 1,
 'hairless': 0,
 'health_issues': 2,
 'hypoallergenic': 0,
 'id': 'abys',
 'indoor': 0,
 'intelligence': 5,
 'lap': 1,
 'life_span': '14 - 15',
 'name': 'Abyssinian',
 'natural': 1,
 'origin': 'Egypt',
 'rare': 0,
 'reference_image_id': '0XYvRd7oD',
 'rex': 0,
 'shedding_level': 2,
 'short_legs': 0,
 'social_needs': 5,
 'stranger_friendly': 5,
 'suppressed_tail': 0,
 'temperament': 'Active, Energetic, Independent, Intelligent, Gentle',
 'vcahospitals_url': 'https://vcahospitals.com/know-your-pet/cat-breeds/abyssinian',
 'vetstreet_url': 'http://www.vetstreet.com/cats/abyssinian',
 'vocalisation': 1,
 'weight': {'imperial': '7  -  10', 'metric': '3 - 5'},
 'wikipedia_url': 'https://en.wikipedia.org/wiki/Abyssinian_(cat)'}

🐶 Dog Data Extraction Overview¶

This function extracts and cleans relevant dog breed information from raw JSON data. It includes:

  • Breed details (id, name, origin, breed_group, etc.)
  • Structured temperament and origin lists
  • Cleaned life_span string, ensuring format consistency (e.g. 1214 → 12-14)
  • Full weight and height dictionaries (if available)

āš™ļø Includes logic to fix malformed life spans with missing hyphens.

InĀ [35]:
import re
import pandas as pd

def extract_dog_values(dog, user_column_value='dog'):
    raw_life_span = dog.get('life_span', '')
    # Clean life_span: remove unwanted characters
    cleaned = re.sub(r'[^0-9\-]', '', raw_life_span).strip()
    
    # Detect and correct patterns like "81-5" or "91-4" using regex.
    match = re.fullmatch(r'(\d{2})-(\d)$', cleaned)
    if match:
        first, second = match.groups()
        # Correcting the pattern where the life span seems broken into "XX-X" format
        cleaned = f"{first}-{second}"
    elif '-' not in cleaned:
        # If no hyphen is found, try to insert one based on the length of the string.
        if len(cleaned) == 4:
            cleaned = cleaned[:2] + '-' + cleaned[2:]
        elif len(cleaned) == 3:
            cleaned = cleaned[:2] + '-' + cleaned[2:]
        elif 0 < len(cleaned) <= 2:
            cleaned = f"{cleaned}-{cleaned}"
    
    filtered_life_span = cleaned

    raw_origin = dog.get('origin', None)
    if isinstance(raw_origin, str):
        origin_list = [o.strip() for o in raw_origin.split(',')]
    elif isinstance(raw_origin, list):
        origin_list = raw_origin
    else:
        origin_list = []

    raw_temperament = dog.get('temperament', '')
    if isinstance(raw_temperament, str):
        temperament_list = [t.strip() for t in raw_temperament.split(',')]
    else:
        temperament_list = []

    values = {
        'id': dog.get('id'),
        'type_of_pet': user_column_value,
        'breed': dog.get('name', ''),
        'origin': origin_list,
        'country_code': dog.get('country_code', ''),
        'life_span': filtered_life_span,
        'temperament': temperament_list,
        'weight': dog.get('weight', ''),
        'height': dog.get('height', ''),
        'bred_for': dog.get('bred_for', ''),
        'breed_group': dog.get('breed_group', '')
    }
    return values
InĀ [36]:
def extract_cat_values(cat, user_column_value='cat'):
    """
    Extracts cat breed information into a dictionary and includes a user-supplied column if provided.

    :param cat: A dictionary containing cat data.
    :param user_column_value: Optional user-supplied data for the new_column field.
    :return: A dictionary representing a cat document.
    """

    # Process origin
    raw_origin = cat.get('origin', '')
    if isinstance(raw_origin, str):
        origin_list = [o.strip() for o in raw_origin.split(',')] if raw_origin else []
    elif isinstance(raw_origin, list):
        origin_list = raw_origin
    else:
        origin_list = []

    # Process country_code
    raw_country_code = cat.get('country_code', '')
    if isinstance(raw_country_code, str):
        country_code_list = [c.strip() for c in raw_country_code.split(',')] if raw_country_code else []
    elif isinstance(raw_country_code, list):
        country_code_list = raw_country_code
    else:
        country_code_list = []

    # Process temperament
    raw_temperament = cat.get('temperament', '')
    if isinstance(raw_temperament, str):
        temperament_list = [t.strip() for t in raw_temperament.split(',')] if raw_temperament else []
    elif isinstance(raw_temperament, list):
        temperament_list = raw_temperament
    else:
        temperament_list = []

    values = {
        'id': cat.get('id', ''),
        'type_of_pet': user_column_value,
        'breed': cat.get('name', ''),
        'origin': origin_list,
        'country_code': country_code_list,
        'life_span': cat.get('life_span', ''),
        'temperament': temperament_list,
        'weight': cat.get('weight', ''),  # Changed here: no longer accessing ['metric']
        'description': cat.get('description', ''),
        'affection_level': cat.get('affection_level', ''),
        'energy_level': cat.get('energy_level', ''),
        'dog_friendly': cat.get('dog_friendly', ''),
        'child_friendly': cat.get('child_friendly', ''),
        'intelligence': cat.get('intelligence', ''),
        'hairless': cat.get('hairless', ''),
        'health_issues': cat.get('health_issues', ''),
        'hypoallergenic': cat.get('hypoallergenic', ''),
        'experimental': cat.get('experimental', ''),
        'indoor': cat.get('indoor', ''),
        'natural': cat.get('natural', ''),
        'rare': cat.get('rare', ''),
        'shedding_level': cat.get('shedding_level', ''),
        'social_needs': cat.get('social_needs', ''),
        'stranger_friendly': cat.get('stranger_friendly', '')
    }

    # Print the key-value pairs in vertical format for debugging/display
    for key, value in values.items():
        print(f"{key}: {value}")

    return values
InĀ [37]:
# generate list of characters including digits
list_characters = [char for char in string.ascii_lowercase + string.digits]
print(list_characters)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
InĀ [38]:
# Initialize an empty list and a set to track unique dog IDs
list_dogs = []
seen_dog_ids = set()

# Download/search dogs by starting char
for i, char in enumerate(list_characters):
    print(f'- {char} ({i+1}/{len(list_characters)})', end='\r')
    url = f'{API_URL_1}?f={char}'
    r = requests.get(url)
    data = r.json()

    if data:  # If there's data, proceed to extract values
        for dog in data:
            dog_id = dog.get('id')
            if dog_id not in seen_dog_ids:
                values = extract_dog_values(dog)
                list_dogs.append(values)
                seen_dog_ids.add(dog_id)  # Add dog ID to the set to track it
                
    time.sleep(1)  # Throttle requests to avoid being rate-limited
- 9 (36/36)
InĀ [Ā ]:
# Initialize an empty list and a set to track unique cats IDs
list_cats = []
seen_cats_ids = set()

# Download/search cats by starting char
for i, char in enumerate(list_characters):
    print(f'- {char} ({i+1}/{len(list_characters)})', end='\r')
    url = f'{API_URL_2}?f={char}'
    r = requests.get(url)
    data = r.json()

    if data:  # If there's data, proceed to extract values
        for cat in data:
            cat_id = cat.get('id')
            if cat_id not in seen_cats_ids:
                values = extract_cat_values(cat)
                list_cats.append(values)
                seen_cats_ids.add(cat_id)  # Add cat ID to the set to track it
                
    time.sleep(1)  # Throttle requests to avoid being rate-limited

šŸ“¦ NoSQL Schema Description – Pets DB¶

This NoSQL schema is designed to organize and store structured pet data — specifically for cats and dogs — using a document-based model ideal for MongoDB.

šŸ—‚ļø Structure Overview¶

  • pets collection
    Serves as the central entry point. Each document includes a unique _id and a type_of_pet field (e.g., "cat" or "dog").

  • cats collection
    Linked by _id, each document includes:

    • breed
    • affection_level, intelligence, friendliness
    • Physical traits like hairless, hypoallergenic, weight
  • dogs collection
    Also linked by _id, each document includes:

    • breed
    • bred_for (purpose of breed origin)
    • weight, height, temperament, and breed_group

šŸ” Why This Design?¶

  • Keeps pet types cleanly separated while still linked
  • Supports flexible, schema-less attributes per animal type
  • Ideal for querying pets by type or specific traits
  • Great for learning NoSQL modeling and working with real-world API data

pic1.jpg pic6.jpeg

Collections creations¶

InĀ [40]:
# insert the list of dogs (=documents) into MongoDB collection "dogs"
dogs.insert_many(list_dogs);
InĀ [41]:
# count number of documents inserted
dogs.count_documents({})
Out[41]:
172
InĀ [42]:
# insert the list of cats (=documents) into MongoDB collection "cats"
cats.insert_many(list_cats);
InĀ [43]:
# count number of documents inserted into cats
print(cats.count_documents({}))
67
InĀ [44]:
# insert the list of cats & dogs (=documents) into MongoDB collection "pets"
pets.insert_many(list_dogs);
pets.insert_many(list_cats);
InĀ [45]:
# count number of documents inserted into pets
print(pets.count_documents({}))
239
InĀ [46]:
# Dictionary to store database and collection info
all_collections = []

# Iterate over all databases
for db_name in client.list_database_names():
    db = client[db_name]
    for coll_name in db.list_collection_names():
        all_collections.append({"database": db_name, "collection": coll_name})

# Convert to DataFrame
colls_df = pd.DataFrame(all_collections)
print(colls_df)
  database       collection
0    admin   system.version
1   catsdb        type_cats
2   config  system.sessions
3   dogsdb        type_dogs
4    local      startup_log
5   petsdb        type_pets
InĀ [47]:
colls = pd.DataFrame(client['catsdb'].list_collection_names(), columns=["collection"])
colls
Out[47]:
collection
0 type_cats
InĀ [48]:
colls = pd.DataFrame(client['dogsdb'].list_collection_names(), columns=["collection"])
colls
Out[48]:
collection
0 type_dogs
InĀ [49]:
colls = pd.DataFrame(client['petsdb'].list_collection_names(), columns=["collection"])
colls
Out[49]:
collection
0 type_pets
InĀ [50]:
# get one dog from MongoDB
(dogs.find_one())
Out[50]:
{'_id': ObjectId('67ed6529b16d68169fd97047'),
 'id': 1,
 'type_of_pet': 'dog',
 'breed': 'Affenpinscher',
 'origin': ['Germany', 'France'],
 'country_code': '',
 'life_span': '10-12',
 'temperament': ['Stubborn',
  'Curious',
  'Playful',
  'Adventurous',
  'Active',
  'Fun-loving'],
 'weight': {'imperial': '6 - 13', 'metric': '3 - 6'},
 'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
 'bred_for': 'Small rodent hunting, lapdog',
 'breed_group': 'Toy'}
InĀ [51]:
# get 5 dogs from MongoDB and display as datframe
r = dogs.aggregate([
      {"$limit": 5},
])

pd.DataFrame(r)
Out[51]:
_id id type_of_pet breed origin country_code life_span temperament weight height bred_for breed_group
0 67ed6529b16d68169fd97047 1 dog Affenpinscher [Germany, France] 10-12 [Stubborn, Curious, Playful, Adventurous, Acti... {'imperial': '6 - 13', 'metric': '3 - 6'} {'imperial': '9 - 11.5', 'metric': '23 - 29'} Small rodent hunting, lapdog Toy
1 67ed6529b16d68169fd97048 2 dog Afghan Hound [Afghanistan, Iran, Pakistan] AG 10-13 [Aloof, Clownish, Dignified, Independent, Happy] {'imperial': '50 - 60', 'metric': '23 - 27'} {'imperial': '25 - 27', 'metric': '64 - 69'} Coursing and hunting Hound
2 67ed6529b16d68169fd97049 3 dog African Hunting Dog [] 11-11 [Wild, Hardworking, Dutiful] {'imperial': '44 - 66', 'metric': '20 - 30'} {'imperial': '30', 'metric': '76'} A wild pack animal
3 67ed6529b16d68169fd9704a 4 dog Airedale Terrier [United Kingdom, England] 10-13 [Outgoing, Friendly, Alert, Confident, Intelli... {'imperial': '40 - 65', 'metric': '18 - 29'} {'imperial': '21 - 23', 'metric': '53 - 58'} Badger, otter hunting Terrier
4 67ed6529b16d68169fd9704b 5 dog Akbash Dog [] 10-12 [Loyal, Independent, Intelligent, Brave] {'imperial': '90 - 120', 'metric': '41 - 54'} {'imperial': '28 - 34', 'metric': '71 - 86'} Sheep guarding Working

āœ… Fixing Inconsistencies in life_span Values¶

Inconsistencies were found in the life_span field of the pets_collection. The values 81-5 and 91-4 were incorrectly formatted. These were corrected as follows:

  • 81-5 was updated to 8-15
  • 91-4 was updated to 9-14

The issue was resolved using the update_many function in MongoDB to ensure a consistent format for the lifespan values_

InĀ [52]:
db = client["dogsdb"]
pets_collection = db["type_dogs"]

# Update the "life_span" field in the collection to fix the ranges
pets_collection.update_many(
    {"life_span": "81-5"},  # Condition to find the incorrect value
    {"$set": {"life_span": "8-15"}}  # Update to the corrected value
)

pets_collection.update_many(
    {"life_span": "91-4"},  # Condition to find the incorrect value
    {"$set": {"life_span": "9-14"}}  # Update to the corrected value
)

# Verify the update by printing the distinct "life_span" values
updated_life_spans = pets_collection.distinct("life_span")
print(updated_life_spans)
['10-10', '10-11', '10-12', '10-13', '10-14', '10-15', '10-16', '10-18', '11-11', '11-13', '11-14', '11-15', '12-12', '12-13', '12-14', '12-15', '12-16', '12-18', '13-14', '13-15', '13-16', '13-17', '14-15', '14-16', '14-18', '15-15', '15-18', '15-20', '18-18', '6-8', '7-10', '8-10', '8-12', '8-15', '9-11', '9-14']
InĀ [53]:
# check collection structure
r = cats.aggregate([
    {"$project": {"_id": 0}},
    {"$limit": 5},
])
pd.DataFrame(r)
Out[53]:
id type_of_pet breed origin country_code life_span temperament weight description affection_level ... hairless health_issues hypoallergenic experimental indoor natural rare shedding_level social_needs stranger_friendly
0 abys cat Abyssinian [Egypt] [EG] 14 - 15 [Active, Energetic, Independent, Intelligent, ... {'imperial': '7 - 10', 'metric': '3 - 5'} The Abyssinian is easy to care for, and a joy ... 5 ... 0 2 0 0 0 1 0 2 5 5
1 aege cat Aegean [Greece] [GR] 9 - 12 [Affectionate, Social, Intelligent, Playful, A... {'imperial': '7 - 10', 'metric': '3 - 5'} Native to the Greek islands known as the Cycla... 4 ... 0 1 0 0 0 0 0 3 4 4
2 abob cat American Bobtail [United States] [US] 11 - 15 [Intelligent, Interactive, Lively, Playful, Se... {'imperial': '7 - 16', 'metric': '3 - 7'} American Bobtails are loving and incredibly in... 5 ... 0 1 0 0 0 0 0 3 3 3
3 acur cat American Curl [United States] [US] 12 - 16 [Affectionate, Curious, Intelligent, Interacti... {'imperial': '5 - 10', 'metric': '2 - 5'} Distinguished by truly unique ears that curl b... 5 ... 0 1 0 0 0 0 0 3 3 3
4 asho cat American Shorthair [United States] [US] 15 - 17 [Active, Curious, Easy Going, Playful, Calm] {'imperial': '8 - 15', 'metric': '4 - 7'} The American Shorthair is known for its longev... 5 ... 0 3 0 0 0 1 0 3 4 3

5 rows Ɨ 24 columns

InĀ [54]:
# List databases
client.list_database_names()
Out[54]:
['admin', 'catsdb', 'config', 'dogsdb', 'local', 'petsdb']

Transform

InĀ [55]:
# selection of specific columns of interest 
r = dogs.aggregate([
  {"$limit": 10},
  {
    "$project": {
      "_id": 0,
      "type_of_pet": 1,
      "breed": 1,
      "country_code": 1,
      "origin": 1,
      "life_span": 1,
      "weight": 1,
      "temperament":2,
    }
  }
])

filtered_pet = pd.DataFrame(r)
filtered_pet
Out[55]:
type_of_pet breed origin country_code life_span temperament weight
0 dog Affenpinscher [Germany, France] 10-12 [Stubborn, Curious, Playful, Adventurous, Acti... {'imperial': '6 - 13', 'metric': '3 - 6'}
1 dog Afghan Hound [Afghanistan, Iran, Pakistan] AG 10-13 [Aloof, Clownish, Dignified, Independent, Happy] {'imperial': '50 - 60', 'metric': '23 - 27'}
2 dog African Hunting Dog [] 11-11 [Wild, Hardworking, Dutiful] {'imperial': '44 - 66', 'metric': '20 - 30'}
3 dog Airedale Terrier [United Kingdom, England] 10-13 [Outgoing, Friendly, Alert, Confident, Intelli... {'imperial': '40 - 65', 'metric': '18 - 29'}
4 dog Akbash Dog [] 10-12 [Loyal, Independent, Intelligent, Brave] {'imperial': '90 - 120', 'metric': '41 - 54'}
5 dog Akita [] 10-14 [Docile, Alert, Responsive, Dignified, Compose... {'imperial': '65 - 115', 'metric': '29 - 52'}
6 dog Alapaha Blue Blood Bulldog [] 12-13 [Loving, Protective, Trainable, Dutiful, Respo... {'imperial': '55 - 90', 'metric': '25 - 41'}
7 dog Alaskan Husky [] 10-13 [Friendly, Energetic, Loyal, Gentle, Confident] {'imperial': '38 - 50', 'metric': '17 - 23'}
8 dog Alaskan Malamute [] 12-15 [Friendly, Affectionate, Devoted, Loyal, Digni... {'imperial': '65 - 100', 'metric': '29 - 45'}
9 dog American Bulldog [] 10-12 [Friendly, Assertive, Energetic, Loyal, Gentle... {'imperial': '60 - 120', 'metric': '27 - 54'}

šŸ”„ Transformation¶

šŸŒ Adding Geo Coordinates to type_dogs & type_cats¶

Geo location data is added to both collections using the $set operator with updateMany.

šŸ› ļø Action:¶

  • A new field geocord (geo coordinates) is added to all documents in:
    • type_dogs
    • type_cats

This allows for future geospatial queries and visualizations, improving data usability for mapping or location-based features.

InĀ [56]:
db = client["dogsdb"]
pets_collection = db["type_dogs"]  

# Add a new field "geocord" to every document
result = pets_collection.update_many(
    {},
    {"$set": {"geocord":""}}
)

print(f"Modified {result.modified_count} documents.")
Modified 172 documents.

Adding fields via Update many via set

InĀ [57]:
db = client["catsdb"]
pets_collection = db["type_cats"]  # or whichever collection name you use

# Add a new field "geocord" to every document
result = pets_collection.update_many(
    {},
    {"$set": {"geocord":""}}
)

print(f"Modified {result.modified_count} documents.")
Modified 67 documents.

We check the new column

InĀ [58]:
db = client["dogsdb"]
pets_collection = db["type_dogs"]

# Fetch a document to check (for example, the first one)
doc = pets_collection.find_one({})
pp.pprint(doc)
{'_id': ObjectId('67ed6529b16d68169fd97047'),
 'bred_for': 'Small rodent hunting, lapdog',
 'breed': 'Affenpinscher',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
 'id': 1,
 'life_span': '10-12',
 'origin': ['Germany', 'France'],
 'temperament': ['Stubborn',
                 'Curious',
                 'Playful',
                 'Adventurous',
                 'Active',
                 'Fun-loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
InĀ [59]:
db = client["catsdb"]
pets_collection = db["type_cats"]

# Fetch a document to check (for example, the first one)
doc = pets_collection.find_one({})
pp.pprint(doc)
{'_id': ObjectId('67ed652ab16d68169fd970f3'),
 'affection_level': 5,
 'breed': 'Abyssinian',
 'child_friendly': 3,
 'country_code': ['EG'],
 'description': 'The Abyssinian is easy to care for, and a joy to have in your '
                'home. They’re affectionate cats and love both people and '
                'other animals.',
 'dog_friendly': 4,
 'energy_level': 5,
 'experimental': 0,
 'geocord': '',
 'hairless': 0,
 'health_issues': 2,
 'hypoallergenic': 0,
 'id': 'abys',
 'indoor': 0,
 'intelligence': 5,
 'life_span': '14 - 15',
 'natural': 1,
 'origin': ['Egypt'],
 'rare': 0,
 'shedding_level': 2,
 'social_needs': 5,
 'stranger_friendly': 5,
 'temperament': ['Active', 'Energetic', 'Independent', 'Intelligent', 'Gentle'],
 'type_of_pet': 'cat',
 'weight': {'imperial': '7  -  10', 'metric': '3 - 5'}}

🌐 Source of Extracting Geo Coordinates¶

Geo coordinates are derived based on each pet’s country of origin.

šŸ—ŗļø How It's Done:¶

  • The origin field (e.g., "Germany", "France") is used as a reference.
  • A separate dataset or API (such as openstreetmap) provides latitude and longitude for each country.
  • These coordinates are mapped and inserted into the geocord field in both type_dogs and type_cats.

This enriches the dataset for future use in geospatial analysis or map visualizations.

InĀ [60]:
url = "https://nominatim.openstreetmap.org/search"
params = {
    'country': 'Germany',
    'format': 'json'
}
headers = {
    'User-Agent': 'MyAwesomeApp/1.0 (myemail@example.com)'
}

response = requests.get(url, params=params, headers=headers)
data = response.json()

pp.pprint(data)
[{'addresstype': 'country',
  'boundingbox': ['47.2701114', '55.0991610', '5.8663153', '15.0419309'],
  'class': 'boundary',
  'display_name': 'Deutschland',
  'importance': 0.9450694379594134,
  'lat': '51.1638175',
  'licence': 'Data Ā© OpenStreetMap contributors, ODbL 1.0. '
             'http://osm.org/copyright',
  'lon': '10.4478313',
  'name': 'Deutschland',
  'osm_id': 51477,
  'osm_type': 'relation',
  'place_id': 125322550,
  'place_rank': 4,
  'type': 'administrative'}]

Extracting origin from from type_dogs collection, and adding coordinates to empty column 'geocord'

InĀ [61]:
import time
import requests

db = client["dogsdb"]
collection = db["type_dogs"]

for pet in collection.find():
    origin_field = pet.get("origin")

    # Skip if origin is missing
    if not origin_field:
        continue

    # Normalize origin to a string: take the first item if it's a list
    if isinstance(origin_field, list) and origin_field:
        origin_value = origin_field[0]
    elif isinstance(origin_field, str):
        origin_value = origin_field.split(",")[0].strip()
    else:
        # Unsupported format
        continue

    # Skip if the value is "Unknown"
    if origin_value.strip().lower() == "N/A":
        continue

    # Prepare the request to Nominatim
    url = "https://nominatim.openstreetmap.org/search"
    params = {
        "country": origin_value,
        "format": "json"
    }
    headers = {
        "User-Agent": "MyAwesomeApp/1.0 (myemail@example.com)"
    }

    try:
        response = requests.get(url, params=params, headers=headers, timeout=10)
        response.raise_for_status()
        data = response.json()
    except requests.RequestException as e:
        print(f"Request failed for origin '{origin_value}': {e}")
        continue

    if data:
        try:
            lat = float(data[0].get("lat", 0))
            lon = float(data[0].get("lon", 0))

            result = collection.update_one(
                {"_id": pet["_id"]},
                {"$set": {"geocord": {"lat": lat, "lon": lon}}}
            )

            if result.matched_count > 0:
                print(f"Updated doc _id={pet['_id']} with lat={lat}, lon={lon}")
            else:
                print(f"No document matched for _id={pet['_id']}")
        except (ValueError, KeyError) as e:
            print(f"Failed to parse lat/lon for origin '{origin_value}': {e}")
    else:
        print(f"No results for origin '{origin_value}'")

    time.sleep(1)

# Confirm an example update
check_pet = collection.find_one({"_id": pet["_id"]})
print("Example updated pet with geocord:", check_pet.get("geocord"))
Updated doc _id=67ed6529b16d68169fd97047 with lat=51.1638175, lon=10.4478313
Updated doc _id=67ed6529b16d68169fd97048 with lat=33.7680065, lon=66.2385139
Request failed for origin '': 400 Client Error: Bad Request for url: https://nominatim.openstreetmap.org/search?country=&format=json
Updated doc _id=67ed6529b16d68169fd9704a with lat=54.7023545, lon=-3.2765753
Request failed for origin '': 400 Client Error: Bad Request for url: https://nominatim.openstreetmap.org/search?country=&format=json
Example updated pet with geocord: 

We check the results

InĀ [62]:
# Query documents that have a 'geocord' field
updated_docs = collection.find({"geocord": {"$exists": True}})

for doc in updated_docs:
    pp.pprint(doc)
{'_id': ObjectId('67ed6529b16d68169fd97047'),
 'bred_for': 'Small rodent hunting, lapdog',
 'breed': 'Affenpinscher',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': {'lat': 51.1638175, 'lon': 10.4478313},
 'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
 'id': 1,
 'life_span': '10-12',
 'origin': ['Germany', 'France'],
 'temperament': ['Stubborn',
                 'Curious',
                 'Playful',
                 'Adventurous',
                 'Active',
                 'Fun-loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd97048'),
 'bred_for': 'Coursing and hunting',
 'breed': 'Afghan Hound',
 'breed_group': 'Hound',
 'country_code': 'AG',
 'geocord': {'lat': 33.7680065, 'lon': 66.2385139},
 'height': {'imperial': '25 - 27', 'metric': '64 - 69'},
 'id': 2,
 'life_span': '10-13',
 'origin': ['Afghanistan', 'Iran', 'Pakistan'],
 'temperament': ['Aloof', 'Clownish', 'Dignified', 'Independent', 'Happy'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 60', 'metric': '23 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97049'),
 'bred_for': 'A wild pack animal',
 'breed': 'African Hunting Dog',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '30', 'metric': '76'},
 'id': 3,
 'life_span': '11-11',
 'origin': [''],
 'temperament': ['Wild', 'Hardworking', 'Dutiful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '44 - 66', 'metric': '20 - 30'}}
{'_id': ObjectId('67ed6529b16d68169fd9704a'),
 'bred_for': 'Badger, otter hunting',
 'breed': 'Airedale Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': {'lat': 54.7023545, 'lon': -3.2765753},
 'height': {'imperial': '21 - 23', 'metric': '53 - 58'},
 'id': 4,
 'life_span': '10-13',
 'origin': ['United Kingdom', 'England'],
 'temperament': ['Outgoing',
                 'Friendly',
                 'Alert',
                 'Confident',
                 'Intelligent',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 65', 'metric': '18 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd9704b'),
 'bred_for': 'Sheep guarding',
 'breed': 'Akbash Dog',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '28 - 34', 'metric': '71 - 86'},
 'id': 5,
 'life_span': '10-12',
 'origin': [''],
 'temperament': ['Loyal', 'Independent', 'Intelligent', 'Brave'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '90 - 120', 'metric': '41 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd9704c'),
 'bred_for': 'Hunting bears',
 'breed': 'Akita',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 28', 'metric': '61 - 71'},
 'id': 6,
 'life_span': '10-14',
 'origin': [],
 'temperament': ['Docile',
                 'Alert',
                 'Responsive',
                 'Dignified',
                 'Composed',
                 'Friendly',
                 'Receptive',
                 'Faithful',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '65 - 115', 'metric': '29 - 52'}}
{'_id': ObjectId('67ed6529b16d68169fd9704d'),
 'bred_for': 'Guarding',
 'breed': 'Alapaha Blue Blood Bulldog',
 'breed_group': 'Mixed',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '18 - 24', 'metric': '46 - 61'},
 'id': 7,
 'life_span': '12-13',
 'origin': [],
 'temperament': ['Loving', 'Protective', 'Trainable', 'Dutiful', 'Responsible'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '55 - 90', 'metric': '25 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd9704e'),
 'bred_for': 'Sled pulling',
 'breed': 'Alaskan Husky',
 'breed_group': 'Mixed',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 26', 'metric': '58 - 66'},
 'id': 8,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Friendly', 'Energetic', 'Loyal', 'Gentle', 'Confident'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '38 - 50', 'metric': '17 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd9704f'),
 'bred_for': 'Hauling heavy freight, Sled pulling',
 'breed': 'Alaskan Malamute',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 25', 'metric': '58 - 64'},
 'id': 9,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Friendly',
                 'Affectionate',
                 'Devoted',
                 'Loyal',
                 'Dignified',
                 'Playful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '65 - 100', 'metric': '29 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd97050'),
 'bred_for': '',
 'breed': 'American Bulldog',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
 'id': 10,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Friendly',
                 'Assertive',
                 'Energetic',
                 'Loyal',
                 'Gentle',
                 'Confident',
                 'Dominant'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '60 - 120', 'metric': '27 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd97051'),
 'bred_for': 'Family companion dog',
 'breed': 'American Bully',
 'breed_group': '',
 'country_code': 'US',
 'geocord': '',
 'height': {'imperial': '14 - 17', 'metric': '36 - 43'},
 'id': 11,
 'life_span': '8-15',
 'origin': [],
 'temperament': ['Strong Willed',
                 'Stubborn',
                 'Friendly',
                 'Clownish',
                 'Affectionate',
                 'Loyal',
                 'Obedient',
                 'Intelligent',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30 - 150', 'metric': '14 - 68'}}
{'_id': ObjectId('67ed6529b16d68169fd97052'),
 'bred_for': 'Circus performer',
 'breed': 'American Eskimo Dog',
 'breed_group': 'Non-Sporting',
 'country_code': 'US',
 'geocord': '',
 'height': {'imperial': '15 - 19', 'metric': '38 - 48'},
 'id': 12,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Friendly', 'Alert', 'Reserved', 'Intelligent', 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 40', 'metric': '9 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd97053'),
 'bred_for': 'Companionship',
 'breed': 'American Eskimo Dog (Miniature)',
 'breed_group': '',
 'country_code': 'US',
 'geocord': '',
 'height': {'imperial': '9 - 12', 'metric': '23 - 30'},
 'id': 13,
 'life_span': '13-15',
 'origin': [],
 'temperament': ['Friendly', 'Alert', 'Reserved', 'Intelligent', 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '7 - 10', 'metric': '3 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd97054'),
 'bred_for': 'Fox hunting, scent hound',
 'breed': 'American Foxhound',
 'breed_group': 'Hound',
 'country_code': 'US',
 'geocord': '',
 'height': {'imperial': '21 - 28', 'metric': '53 - 71'},
 'id': 14,
 'life_span': '8-15',
 'origin': [],
 'temperament': ['Kind',
                 'Sweet-Tempered',
                 'Loyal',
                 'Independent',
                 'Intelligent',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '65 - 75', 'metric': '29 - 34'}}
{'_id': ObjectId('67ed6529b16d68169fd97055'),
 'bred_for': 'Fighting',
 'breed': 'American Pit Bull Terrier',
 'breed_group': 'Terrier',
 'country_code': 'US',
 'geocord': '',
 'height': {'imperial': '17 - 21', 'metric': '43 - 53'},
 'id': 15,
 'life_span': '10-15',
 'origin': [],
 'temperament': ['Strong Willed',
                 'Stubborn',
                 'Friendly',
                 'Clownish',
                 'Affectionate',
                 'Loyal',
                 'Obedient',
                 'Intelligent',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30 - 60', 'metric': '14 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97056'),
 'bred_for': '',
 'breed': 'American Staffordshire Terrier',
 'breed_group': 'Terrier',
 'country_code': 'US',
 'geocord': '',
 'height': {'imperial': '17 - 19', 'metric': '43 - 48'},
 'id': 16,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Tenacious',
                 'Friendly',
                 'Devoted',
                 'Loyal',
                 'Attentive',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 60', 'metric': '23 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97057'),
 'bred_for': 'Bird flushing and retrieving',
 'breed': 'American Water Spaniel',
 'breed_group': 'Sporting',
 'country_code': 'US',
 'geocord': '',
 'height': {'imperial': '15 - 18', 'metric': '38 - 46'},
 'id': 17,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Friendly',
                 'Energetic',
                 'Obedient',
                 'Intelligent',
                 'Protective',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 45', 'metric': '11 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97058'),
 'bred_for': 'Livestock herding',
 'breed': 'Anatolian Shepherd Dog',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '27 - 29', 'metric': '69 - 74'},
 'id': 18,
 'life_span': '11-13',
 'origin': [],
 'temperament': ['Steady',
                 'Bold',
                 'Independent',
                 'Confident',
                 'Intelligent',
                 'Proud'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '80 - 150', 'metric': '36 - 68'}}
{'_id': ObjectId('67ed6529b16d68169fd97059'),
 'bred_for': 'Herding livestock, pulling carts, and guarding the farm',
 'breed': 'Appenzeller Sennenhund',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 22', 'metric': '51 - 56'},
 'id': 19,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Reliable', 'Fearless', 'Energetic', 'Lively', 'Self-assured'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '48 - 55', 'metric': '22 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd9705a'),
 'bred_for': 'Cattle herding, herding trials',
 'breed': 'Australian Cattle Dog',
 'breed_group': 'Herding',
 'country_code': 'AU',
 'geocord': '',
 'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
 'id': 21,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Cautious',
                 'Energetic',
                 'Loyal',
                 'Obedient',
                 'Protective',
                 'Brave'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '44 - 62', 'metric': '20 - 28'}}
{'_id': ObjectId('67ed6529b16d68169fd9705b'),
 'bred_for': 'Farm dog, Cattle herding',
 'breed': 'Australian Kelpie',
 'breed_group': 'Herding',
 'country_code': 'AU',
 'geocord': '',
 'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
 'id': 22,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Friendly',
                 'Energetic',
                 'Alert',
                 'Loyal',
                 'Intelligent',
                 'Eager'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '31 - 46', 'metric': '14 - 21'}}
{'_id': ObjectId('67ed6529b16d68169fd9705c'),
 'bred_for': 'Sheep herding',
 'breed': 'Australian Shepherd',
 'breed_group': 'Herding',
 'country_code': 'AU',
 'geocord': '',
 'height': {'imperial': '18 - 23', 'metric': '46 - 58'},
 'id': 23,
 'life_span': '12-16',
 'origin': [],
 'temperament': ['Good-natured',
                 'Affectionate',
                 'Intelligent',
                 'Active',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 65', 'metric': '16 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd9705d'),
 'bred_for': 'Cattle herdering, hunting snakes and rodents',
 'breed': 'Australian Terrier',
 'breed_group': 'Terrier',
 'country_code': 'AU',
 'geocord': '',
 'height': {'imperial': '10 - 11', 'metric': '25 - 28'},
 'id': 24,
 'life_span': '15-15',
 'origin': [],
 'temperament': ['Spirited',
                 'Alert',
                 'Loyal',
                 'Companionable',
                 'Even Tempered',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '14 - 16', 'metric': '6 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd9705e'),
 'bred_for': 'Livestock guardian, hunting',
 'breed': 'Azawakh',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 29', 'metric': '58 - 74'},
 'id': 25,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Aloof',
                 'Affectionate',
                 'Attentive',
                 'Rugged',
                 'Fierce',
                 'Refined'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '33 - 55', 'metric': '15 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd9705f'),
 'bred_for': 'Hunting water game',
 'breed': 'Barbet',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 26', 'metric': '51 - 66'},
 'id': 26,
 'life_span': '13-15',
 'origin': [],
 'temperament': ['Obedient', 'Companionable', 'Intelligent', 'Joyful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 65', 'metric': '18 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd97060'),
 'bred_for': 'Hunting',
 'breed': 'Basenji',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '16 - 17', 'metric': '41 - 43'},
 'id': 28,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Affectionate',
                 'Energetic',
                 'Alert',
                 'Curious',
                 'Playful',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '22 - 24', 'metric': '10 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd97061'),
 'bred_for': 'Hunting on foot.',
 'breed': 'Basset Bleu de Gascogne',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '13 - 15', 'metric': '33 - 38'},
 'id': 29,
 'life_span': '10-14',
 'origin': [],
 'temperament': ['Affectionate',
                 'Lively',
                 'Agile',
                 'Curious',
                 'Happy',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 40', 'metric': '16 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd97062'),
 'bred_for': 'Hunting by scent',
 'breed': 'Basset Hound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '14', 'metric': '36'},
 'id': 30,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Tenacious',
                 'Friendly',
                 'Affectionate',
                 'Devoted',
                 'Sweet-Tempered',
                 'Gentle'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 65', 'metric': '23 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd97063'),
 'bred_for': 'Rabbit, hare hunting',
 'breed': 'Beagle',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '13 - 15', 'metric': '33 - 38'},
 'id': 31,
 'life_span': '13-16',
 'origin': [],
 'temperament': ['Amiable',
                 'Even Tempered',
                 'Excitable',
                 'Determined',
                 'Gentle',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 35', 'metric': '9 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd97064'),
 'bred_for': 'Sheep herding',
 'breed': 'Bearded Collie',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 22', 'metric': '51 - 56'},
 'id': 32,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Self-confidence',
                 'Hardy',
                 'Lively',
                 'Alert',
                 'Intelligent',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 55', 'metric': '20 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd97065'),
 'bred_for': 'Boar herding, hunting, guarding',
 'breed': 'Beauceron',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 27.5', 'metric': '61 - 70'},
 'id': 33,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Fearless', 'Friendly', 'Intelligent', 'Protective', 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '80 - 110', 'metric': '36 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd97066'),
 'bred_for': 'Killing rat, badger, other vermin',
 'breed': 'Bedlington Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '15 - 16', 'metric': '38 - 41'},
 'id': 34,
 'life_span': '14-16',
 'origin': [],
 'temperament': ['Affectionate', 'Spirited', 'Intelligent', 'Good-tempered'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '17 - 23', 'metric': '8 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd97067'),
 'bred_for': 'Stock herding',
 'breed': 'Belgian Malinois',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
 'id': 36,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Watchful',
                 'Alert',
                 'Stubborn',
                 'Friendly',
                 'Confident',
                 'Hard-working',
                 'Active',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 80', 'metric': '18 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd97068'),
 'bred_for': 'Guarding, Drafting, Police work.',
 'breed': 'Belgian Tervuren',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
 'id': 38,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Energetic',
                 'Alert',
                 'Loyal',
                 'Intelligent',
                 'Attentive',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 65', 'metric': '18 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd97069'),
 'bred_for': 'Draft work',
 'breed': 'Bernese Mountain Dog',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 27.5', 'metric': '58 - 70'},
 'id': 41,
 'life_span': '7-10',
 'origin': [],
 'temperament': ['Affectionate', 'Loyal', 'Intelligent', 'Faithful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '65 - 120', 'metric': '29 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd9706a'),
 'bred_for': 'Companion',
 'breed': 'Bichon Frise',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9.5 - 11.5', 'metric': '24 - 29'},
 'id': 42,
 'life_span': '15-15',
 'origin': [],
 'temperament': ['Feisty',
                 'Affectionate',
                 'Cheerful',
                 'Playful',
                 'Gentle',
                 'Sensitive'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '10 - 18', 'metric': '5 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd9706b'),
 'bred_for': 'Hunting raccoons, night hunting',
 'breed': 'Black and Tan Coonhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
 'id': 43,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Easygoing',
                 'Gentle',
                 'Adaptable',
                 'Trusting',
                 'Even Tempered',
                 'Lovable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '65 - 100', 'metric': '29 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd9706c'),
 'bred_for': 'Trailing',
 'breed': 'Bloodhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
 'id': 45,
 'life_span': '8-10',
 'origin': [],
 'temperament': ['Stubborn', 'Affectionate', 'Gentle', 'Even Tempered'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '80 - 110', 'metric': '36 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd9706d'),
 'bred_for': 'Hunting with a superior sense of smell.',
 'breed': 'Bluetick Coonhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21 - 27', 'metric': '53 - 69'},
 'id': 47,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Friendly', 'Intelligent', 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd9706e'),
 'bred_for': 'Guarding the homestead, farm work.',
 'breed': 'Boerboel',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
 'id': 48,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Obedient',
                 'Confident',
                 'Intelligent',
                 'Dominant',
                 'Territorial'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '110 - 200', 'metric': '50 - 91'}}
{'_id': ObjectId('67ed6529b16d68169fd9706f'),
 'bred_for': 'Sheep herder',
 'breed': 'Border Collie',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '18 - 22', 'metric': '46 - 56'},
 'id': 50,
 'life_span': '12-16',
 'origin': [],
 'temperament': ['Tenacious',
                 'Keen',
                 'Energetic',
                 'Responsive',
                 'Alert',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30 - 45', 'metric': '14 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97070'),
 'bred_for': 'Fox bolting, ratting',
 'breed': 'Border Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '11 - 16', 'metric': '28 - 41'},
 'id': 51,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Fearless',
                 'Affectionate',
                 'Alert',
                 'Obedient',
                 'Intelligent',
                 'Even Tempered'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '11.5 - 15.5', 'metric': '5 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd97071'),
 'bred_for': 'Ratting, Companionship',
 'breed': 'Boston Terrier',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '16 - 17', 'metric': '41 - 43'},
 'id': 53,
 'life_span': '11-13',
 'origin': [],
 'temperament': ['Friendly', 'Lively', 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '10 - 25', 'metric': '5 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd97072'),
 'bred_for': 'Cattle herding',
 'breed': 'Bouvier des Flandres',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23.5 - 27.5', 'metric': '60 - 70'},
 'id': 54,
 'life_span': '10-15',
 'origin': [],
 'temperament': ['Protective',
                 'Loyal',
                 'Gentle',
                 'Intelligent',
                 'Familial',
                 'Rational'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '70 - 110', 'metric': '32 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd97073'),
 'bred_for': 'Bull-baiting, guardian',
 'breed': 'Boxer',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21.5 - 25', 'metric': '55 - 64'},
 'id': 55,
 'life_span': '8-10',
 'origin': [],
 'temperament': ['Devoted',
                 'Fearless',
                 'Friendly',
                 'Cheerful',
                 'Energetic',
                 'Loyal',
                 'Playful',
                 'Confident',
                 'Intelligent',
                 'Bright',
                 'Brave',
                 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97074'),
 'bred_for': 'Turkey retrieving',
 'breed': 'Boykin Spaniel',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '14 - 18', 'metric': '36 - 46'},
 'id': 56,
 'life_span': '10-14',
 'origin': [],
 'temperament': ['Friendly',
                 'Energetic',
                 'Companionable',
                 'Intelligent',
                 'Eager',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 40', 'metric': '11 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd97075'),
 'bred_for': 'Versatile gun dog',
 'breed': 'Bracco Italiano',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21.5 - 26.5', 'metric': '55 - 67'},
 'id': 57,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Stubborn',
                 'Affectionate',
                 'Loyal',
                 'Playful',
                 'Companionable',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '55 - 88', 'metric': '25 - 40'}}
{'_id': ObjectId('67ed6529b16d68169fd97076'),
 'bred_for': 'Herding, guarding sheep',
 'breed': 'Briard',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
 'id': 58,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Fearless',
                 'Loyal',
                 'Obedient',
                 'Intelligent',
                 'Faithful',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '70 - 90', 'metric': '32 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd97077'),
 'bred_for': 'Pointing, retrieving',
 'breed': 'Brittany',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17.5 - 20.5', 'metric': '44 - 52'},
 'id': 59,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Agile',
                 'Adaptable',
                 'Quick',
                 'Intelligent',
                 'Attentive',
                 'Happy'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30 - 45', 'metric': '14 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97078'),
 'bred_for': 'Bull baiting, Fighting',
 'breed': 'Bull Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21 - 22', 'metric': '53 - 56'},
 'id': 61,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Trainable', 'Protective', 'Sweet-Tempered', 'Keen', 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97079'),
 'bred_for': "An elegant man's fashion statement",
 'breed': 'Bull Terrier (Miniature)',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 14', 'metric': '25 - 36'},
 'id': 62,
 'life_span': '11-14',
 'origin': [],
 'temperament': ['Trainable',
                 'Protective',
                 'Sweet-Tempered',
                 'Keen',
                 'Active',
                 'Territorial'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 33', 'metric': '11 - 15'}}
{'_id': ObjectId('67ed6529b16d68169fd9707a'),
 'bred_for': 'Estate guardian',
 'breed': 'Bullmastiff',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 27', 'metric': '61 - 69'},
 'id': 64,
 'life_span': '8-12',
 'origin': [],
 'temperament': ['Docile',
                 'Reliable',
                 'Devoted',
                 'Alert',
                 'Loyal',
                 'Reserved',
                 'Loving',
                 'Protective',
                 'Powerful',
                 'Calm',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '100 - 130', 'metric': '45 - 59'}}
{'_id': ObjectId('67ed6529b16d68169fd9707b'),
 'bred_for': 'Bolting of otter, foxes, other vermin',
 'breed': 'Cairn Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9 - 10', 'metric': '23 - 25'},
 'id': 65,
 'life_span': '14-15',
 'origin': [],
 'temperament': ['Hardy',
                 'Fearless',
                 'Assertive',
                 'Gay',
                 'Intelligent',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '13 - 14', 'metric': '6 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd9707c'),
 'bred_for': 'Companion, guard dog, and hunter',
 'breed': 'Cane Corso',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23.5 - 27.5', 'metric': '60 - 70'},
 'id': 67,
 'life_span': '10-11',
 'origin': [],
 'temperament': ['Trainable',
                 'Reserved',
                 'Stable',
                 'Quiet',
                 'Even Tempered',
                 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '88 - 120', 'metric': '40 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd9707d'),
 'bred_for': 'Cattle droving',
 'breed': 'Cardigan Welsh Corgi',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10.5 - 12.5', 'metric': '27 - 32'},
 'id': 68,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Affectionate',
                 'Devoted',
                 'Alert',
                 'Companionable',
                 'Intelligent',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 38', 'metric': '11 - 17'}}
{'_id': ObjectId('67ed6529b16d68169fd9707e'),
 'bred_for': 'Driving livestock',
 'breed': 'Catahoula Leopard Dog',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 26', 'metric': '51 - 66'},
 'id': 69,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Energetic',
                 'Inquisitive',
                 'Independent',
                 'Gentle',
                 'Intelligent',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 95', 'metric': '23 - 43'}}
{'_id': ObjectId('67ed6529b16d68169fd9707f'),
 'bred_for': 'Guard dogs, defending sheep from predators, mainly wolves, '
             'jackals and bears',
 'breed': 'Caucasian Shepherd (Ovcharka)',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 33.5', 'metric': '61 - 85'},
 'id': 70,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Alert', 'Quick', 'Dominant', 'Powerful', 'Calm', 'Strong'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '80 - 100', 'metric': '36 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd97080'),
 'bred_for': 'Flushing small birds, companion',
 'breed': 'Cavalier King Charles Spaniel',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '12 - 13', 'metric': '30 - 33'},
 'id': 71,
 'life_span': '10-14',
 'origin': [],
 'temperament': ['Fearless',
                 'Affectionate',
                 'Sociable',
                 'Patient',
                 'Playful',
                 'Adaptable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '13 - 18', 'metric': '6 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd97081'),
 'bred_for': 'Water Retriever',
 'breed': 'Chesapeake Bay Retriever',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21 - 26', 'metric': '53 - 66'},
 'id': 76,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Affectionate',
                 'Intelligent',
                 'Quiet',
                 'Dominant',
                 'Happy',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '55 - 80', 'metric': '25 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd97082'),
 'bred_for': 'Ratting, lapdog, curio',
 'breed': 'Chinese Crested',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '11 - 13', 'metric': '28 - 33'},
 'id': 78,
 'life_span': '10-14',
 'origin': [],
 'temperament': ['Affectionate',
                 'Sweet-Tempered',
                 'Lively',
                 'Alert',
                 'Playful',
                 'Happy'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '10 - 13', 'metric': '5 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd97083'),
 'bred_for': 'Fighting',
 'breed': 'Chinese Shar-Pei',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '18 - 20', 'metric': '46 - 51'},
 'id': 79,
 'life_span': '10-10',
 'origin': [],
 'temperament': ['Suspicious',
                 'Affectionate',
                 'Devoted',
                 'Reserved',
                 'Independent',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 60', 'metric': '20 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97084'),
 'bred_for': 'Sled pulling',
 'breed': 'Chinook',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
 'id': 80,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Friendly', 'Alert', 'Dignified', 'Intelligent', 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 90', 'metric': '23 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd97085'),
 'bred_for': 'Guardian, cart pulling, hunting',
 'breed': 'Chow Chow',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
 'id': 81,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Aloof', 'Loyal', 'Independent', 'Quiet'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 70', 'metric': '18 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97086'),
 'bred_for': 'Bird flushing, retrieving',
 'breed': 'Clumber Spaniel',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
 'id': 84,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Affectionate',
                 'Loyal',
                 'Dignified',
                 'Gentle',
                 'Calm',
                 'Great-hearted'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '55 - 85', 'metric': '25 - 39'}}
{'_id': ObjectId('67ed6529b16d68169fd97087'),
 'bred_for': 'Bird flushing, retrieving',
 'breed': 'Cocker Spaniel',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '14 - 15', 'metric': '36 - 38'},
 'id': 86,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Trainable',
                 'Friendly',
                 'Affectionate',
                 'Playful',
                 'Quiet',
                 'Faithful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd97088'),
 'bred_for': 'Hunting the American woodcock',
 'breed': 'Cocker Spaniel (American)',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '14 - 15', 'metric': '36 - 38'},
 'id': 87,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Outgoing',
                 'Sociable',
                 'Trusting',
                 'Joyful',
                 'Even Tempered',
                 'Merry'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd97089'),
 'bred_for': 'Accompanying ladies on long sea voyages, ratters onboard ship.',
 'breed': 'Coton de Tulear',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9 - 11', 'metric': '23 - 28'},
 'id': 89,
 'life_span': '13-16',
 'origin': [],
 'temperament': ['Affectionate',
                 'Lively',
                 'Playful',
                 'Intelligent',
                 'Trainable',
                 'Vocal'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '9 - 15', 'metric': '4 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd9708a'),
 'bred_for': 'Carriage dog - trot alongside carriages to protect the occupants '
             'from banditry or other interference',
 'breed': 'Dalmatian',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '19 - 23', 'metric': '48 - 58'},
 'id': 92,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Outgoing',
                 'Friendly',
                 'Energetic',
                 'Playful',
                 'Sensitive',
                 'Intelligent',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 55', 'metric': '23 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd9708b'),
 'bred_for': 'Guardian',
 'breed': 'Doberman Pinscher',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 28', 'metric': '61 - 71'},
 'id': 94,
 'life_span': '10-10',
 'origin': [],
 'temperament': ['Fearless',
                 'Energetic',
                 'Alert',
                 'Loyal',
                 'Obedient',
                 'Confident',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '66 - 88', 'metric': '30 - 40'}}
{'_id': ObjectId('67ed6529b16d68169fd9708c'),
 'bred_for': 'Big-game hunting',
 'breed': 'Dogo Argentino',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23.5 - 27', 'metric': '60 - 69'},
 'id': 95,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Friendly',
                 'Affectionate',
                 'Cheerful',
                 'Loyal',
                 'Tolerant',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '80 - 100', 'metric': '36 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd9708d'),
 'bred_for': 'Farms, watchdog, guard duty',
 'breed': 'Dutch Shepherd',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 24.5', 'metric': '56 - 62'},
 'id': 98,
 'life_span': '15-15',
 'origin': [],
 'temperament': ['Reliable',
                 'Affectionate',
                 'Alert',
                 'Loyal',
                 'Obedient',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd9708e'),
 'bred_for': 'Bird setting, retrieving',
 'breed': 'English Setter',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 25', 'metric': '61 - 64'},
 'id': 101,
 'life_span': '12-12',
 'origin': [],
 'temperament': ['Strong Willed',
                 'Mischievous',
                 'Affectionate',
                 'Energetic',
                 'Playful',
                 'Companionable',
                 'Gentle',
                 'Hard-working',
                 'Intelligent',
                 'Eager',
                 'People-Oriented'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd9708f'),
 'bred_for': 'Herding & guarding livestock, farm watch dog',
 'breed': 'English Shepherd',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '18 - 23', 'metric': '46 - 58'},
 'id': 102,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Kind',
                 'Energetic',
                 'Independent',
                 'Adaptable',
                 'Intelligent',
                 'Bossy'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '44 - 66', 'metric': '20 - 30'}}
{'_id': ObjectId('67ed6529b16d68169fd97090'),
 'bred_for': 'Bird flushing, retrieving',
 'breed': 'English Springer Spaniel',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '19 - 20', 'metric': '48 - 51'},
 'id': 103,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Affectionate',
                 'Cheerful',
                 'Alert',
                 'Intelligent',
                 'Attentive',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 50', 'metric': '16 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd97091'),
 'bred_for': 'Companion of kings',
 'breed': 'English Toy Spaniel',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10', 'metric': '25'},
 'id': 104,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Affectionate',
                 'Reserved',
                 'Playful',
                 'Gentle',
                 'Happy',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '8 - 14', 'metric': '4 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd97092'),
 'bred_for': 'Rat-baiting',
 'breed': 'English Toy Terrier',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
 'id': 105,
 'life_span': '12-13',
 'origin': [],
 'temperament': ['Stubborn',
                 'Alert',
                 'Companionable',
                 'Intelligent',
                 'Cunning',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '6 - 8', 'metric': '3 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd97093'),
 'bred_for': 'Companionship',
 'breed': 'Eurasier',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20.5 - 23.5', 'metric': '52 - 60'},
 'id': 107,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Alert',
                 'Reserved',
                 'Intelligent',
                 'Even Tempered',
                 'Watchful',
                 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 70', 'metric': '18 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97094'),
 'bred_for': 'Bird flushing, retrieving',
 'breed': 'Field Spaniel',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17 - 18', 'metric': '43 - 46'},
 'id': 108,
 'life_span': '11-15',
 'origin': [],
 'temperament': ['Docile',
                 'Cautious',
                 'Sociable',
                 'Sensitive',
                 'Adaptable',
                 'Familial'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 50', 'metric': '16 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd97095'),
 'bred_for': 'Herding reindeer',
 'breed': 'Finnish Lapphund',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '16 - 21', 'metric': '41 - 53'},
 'id': 110,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Friendly', 'Keen', 'Faithful', 'Calm', 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '33 - 53', 'metric': '15 - 24'}}
{'_id': ObjectId('67ed6529b16d68169fd97096'),
 'bred_for': 'Hunting birds, small mammals',
 'breed': 'Finnish Spitz',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '15.5 - 20', 'metric': '39 - 51'},
 'id': 111,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Playful',
                 'Loyal',
                 'Independent',
                 'Intelligent',
                 'Happy',
                 'Vocal'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '23 - 28', 'metric': '10 - 13'}}
{'_id': ObjectId('67ed6529b16d68169fd97097'),
 'bred_for': 'Lapdog',
 'breed': 'French Bulldog',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '11 - 12', 'metric': '28 - 30'},
 'id': 113,
 'life_span': '9-11',
 'origin': [],
 'temperament': ['Playful',
                 'Affectionate',
                 'Keen',
                 'Sociable',
                 'Lively',
                 'Alert',
                 'Easygoing',
                 'Patient',
                 'Athletic',
                 'Bright'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '28', 'metric': '13'}}
{'_id': ObjectId('67ed6529b16d68169fd97098'),
 'bred_for': 'Watchdog, Hunting vermin on the farm.',
 'breed': 'German Pinscher',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
 'id': 114,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Spirited',
                 'Lively',
                 'Intelligent',
                 'Loving',
                 'Even Tempered',
                 'Familial'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 45', 'metric': '11 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97099'),
 'bred_for': 'Herding, Guard dog',
 'breed': 'German Shepherd Dog',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
 'id': 115,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Alert',
                 'Loyal',
                 'Obedient',
                 'Curious',
                 'Confident',
                 'Intelligent',
                 'Watchful',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 90', 'metric': '23 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd9709a'),
 'bred_for': 'General hunting',
 'breed': 'German Shorthaired Pointer',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21 - 25', 'metric': '53 - 64'},
 'id': 116,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Boisterous',
                 'Bold',
                 'Affectionate',
                 'Intelligent',
                 'Cooperative',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 70', 'metric': '20 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd9709b'),
 'bred_for': 'Herding, guarding',
 'breed': 'Giant Schnauzer',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23.5 - 27.5', 'metric': '60 - 70'},
 'id': 119,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Strong Willed',
                 'Kind',
                 'Loyal',
                 'Intelligent',
                 'Dominant',
                 'Powerful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '65 - 90', 'metric': '29 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd9709c'),
 'bred_for': 'Rid the home and farm of vermin, and hunt badger and fox',
 'breed': 'Glen of Imaal Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '12.5 - 14', 'metric': '32 - 36'},
 'id': 120,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Spirited',
                 'Agile',
                 'Loyal',
                 'Gentle',
                 'Active',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '32 - 40', 'metric': '15 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd9709d'),
 'bred_for': 'Retrieving',
 'breed': 'Golden Retriever',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21.5 - 24', 'metric': '55 - 61'},
 'id': 121,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Intelligent',
                 'Kind',
                 'Reliable',
                 'Friendly',
                 'Trustworthy',
                 'Confident'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '55 - 75', 'metric': '25 - 34'}}
{'_id': ObjectId('67ed6529b16d68169fd9709e'),
 'bred_for': 'Find and point gamebirds',
 'breed': 'Gordon Setter',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
 'id': 123,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Fearless', 'Alert', 'Loyal', 'Confident', 'Gay', 'Eager'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd9709f'),
 'bred_for': 'Hunting & holding boars, Guardian',
 'breed': 'Great Dane',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '28 - 32', 'metric': '71 - 81'},
 'id': 124,
 'life_span': '7-10',
 'origin': [],
 'temperament': ['Friendly',
                 'Devoted',
                 'Reserved',
                 'Gentle',
                 'Confident',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '110 - 190', 'metric': '50 - 86'}}
{'_id': ObjectId('67ed6529b16d68169fd970a0'),
 'bred_for': 'Sheep guardian',
 'breed': 'Great Pyrenees',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '25 - 32', 'metric': '64 - 81'},
 'id': 125,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Strong Willed',
                 'Fearless',
                 'Affectionate',
                 'Patient',
                 'Gentle',
                 'Confident'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '85 - 115', 'metric': '39 - 52'}}
{'_id': ObjectId('67ed6529b16d68169fd970a1'),
 'bred_for': 'Coursing hares',
 'breed': 'Greyhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '27 - 30', 'metric': '69 - 76'},
 'id': 127,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Affectionate',
                 'Athletic',
                 'Gentle',
                 'Intelligent',
                 'Quiet',
                 'Even Tempered'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd970a2'),
 'bred_for': 'Hunt and kill vermin in stables',
 'breed': 'Griffon Bruxellois',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9 - 11', 'metric': '23 - 28'},
 'id': 128,
 'life_span': '10-15',
 'origin': [],
 'temperament': ['Self-important',
                 'Inquisitive',
                 'Alert',
                 'Companionable',
                 'Sensitive',
                 'Watchful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '12', 'metric': '5'}}
{'_id': ObjectId('67ed6529b16d68169fd970a3'),
 'bred_for': 'Hunting hares by trailing them',
 'breed': 'Harrier',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '18 - 22', 'metric': '46 - 56'},
 'id': 129,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Outgoing',
                 'Friendly',
                 'Cheerful',
                 'Sweet-Tempered',
                 'Tolerant',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 60', 'metric': '18 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970a4'),
 'bred_for': 'Companionship',
 'breed': 'Havanese',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8.5 - 11.5', 'metric': '22 - 29'},
 'id': 130,
 'life_span': '14-15',
 'origin': [],
 'temperament': ['Affectionate',
                 'Responsive',
                 'Playful',
                 'Companionable',
                 'Gentle',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '7 - 13', 'metric': '3 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd970a5'),
 'bred_for': 'Bird setting, retrieving',
 'breed': 'Irish Setter',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 27', 'metric': '61 - 69'},
 'id': 134,
 'life_span': '10-11',
 'origin': [],
 'temperament': ['Affectionate',
                 'Energetic',
                 'Lively',
                 'Independent',
                 'Playful',
                 'Companionable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 70', 'metric': '16 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd970a6'),
 'bred_for': '',
 'breed': 'Irish Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '18', 'metric': '46'},
 'id': 135,
 'life_span': '12-16',
 'origin': [],
 'temperament': ['Respectful',
                 'Lively',
                 'Intelligent',
                 'Dominant',
                 'Protective',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 27', 'metric': '11 - 12'}}
{'_id': ObjectId('67ed6529b16d68169fd970a7'),
 'bred_for': 'Coursing wolves, elk',
 'breed': 'Irish Wolfhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '30 - 35', 'metric': '76 - 89'},
 'id': 137,
 'life_span': '6-8',
 'origin': [],
 'temperament': ['Sweet-Tempered',
                 'Loyal',
                 'Dignified',
                 'Patient',
                 'Thoughtful',
                 'Generous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '105 - 180', 'metric': '48 - 82'}}
{'_id': ObjectId('67ed6529b16d68169fd970a8'),
 'bred_for': 'Lapdog',
 'breed': 'Italian Greyhound',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '13 - 15', 'metric': '33 - 38'},
 'id': 138,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Mischievous',
                 'Affectionate',
                 'Agile',
                 'Athletic',
                 'Companionable',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '7 - 15', 'metric': '3 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970a9'),
 'bred_for': 'Lapdog',
 'breed': 'Japanese Chin',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
 'id': 140,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Alert',
                 'Loyal',
                 'Independent',
                 'Intelligent',
                 'Loving',
                 'Cat-like'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '4 - 9', 'metric': '2 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd970aa'),
 'bred_for': 'Companion',
 'breed': 'Japanese Spitz',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '12 - 15', 'metric': '30 - 38'},
 'id': 141,
 'life_span': '10-16',
 'origin': [],
 'temperament': ['Affectionate',
                 'Obedient',
                 'Playful',
                 'Companionable',
                 'Intelligent',
                 'Proud'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '15 - 19', 'metric': '7 - 9'}}
{'_id': ObjectId('67ed6529b16d68169fd970ab'),
 'bred_for': 'Barge watchdog',
 'breed': 'Keeshond',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17 - 18', 'metric': '43 - 46'},
 'id': 142,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Agile', 'Obedient', 'Playful', 'Quick', 'Sturdy', 'Bright'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 45', 'metric': '16 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd970ac'),
 'bred_for': 'Sheep guardian',
 'breed': 'Komondor',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '25.5 - 27.5', 'metric': '65 - 70'},
 'id': 144,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Steady',
                 'Fearless',
                 'Affectionate',
                 'Independent',
                 'Gentle',
                 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '80 - 100', 'metric': '36 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd970ad'),
 'bred_for': 'Luring ducks into traps - "tolling"',
 'breed': 'Kooikerhondje',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '14 - 16', 'metric': '36 - 41'},
 'id': 145,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Benevolent',
                 'Agile',
                 'Alert',
                 'Intelligent',
                 'Active',
                 'Territorial'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970ae'),
 'bred_for': 'Guardian, hunting large game',
 'breed': 'Kuvasz',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '26 - 30', 'metric': '66 - 76'},
 'id': 147,
 'life_span': '8-10',
 'origin': [],
 'temperament': ['Clownish',
                 'Loyal',
                 'Patient',
                 'Independent',
                 'Intelligent',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '70 - 115', 'metric': '32 - 52'}}
{'_id': ObjectId('67ed6529b16d68169fd970af'),
 'bred_for': 'Water retrieving',
 'breed': 'Labrador Retriever',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21.5 - 24.5', 'metric': '55 - 62'},
 'id': 149,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Kind',
                 'Outgoing',
                 'Agile',
                 'Gentle',
                 'Intelligent',
                 'Trusting',
                 'Even Tempered'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '55 - 80', 'metric': '25 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970b0'),
 'bred_for': 'Water retrieval dog in the marshes of Romagna',
 'breed': 'Lagotto Romagnolo',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '16 - 19', 'metric': '41 - 48'},
 'id': 151,
 'life_span': '14-16',
 'origin': [],
 'temperament': ['Keen',
                 'Loyal',
                 'Companionable',
                 'Loving',
                 'Active',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '24 - 35', 'metric': '11 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd970b1'),
 'bred_for': 'Cattle herding, Ratting, Driving cattle to market.',
 'breed': 'Lancashire Heeler',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
 'id': 153,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Clever', 'Friendly', 'Alert', 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd970b2'),
 'bred_for': 'Guardian, appearance.',
 'breed': 'Leonberger',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '25.5 - 31.5', 'metric': '65 - 80'},
 'id': 155,
 'life_span': '6-8',
 'origin': [],
 'temperament': ['Obedient',
                 'Fearless',
                 'Loyal',
                 'Companionable',
                 'Adaptable',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '120 - 170', 'metric': '54 - 77'}}
{'_id': ObjectId('67ed6529b16d68169fd970b3'),
 'bred_for': 'Guarding inside the home, companion',
 'breed': 'Lhasa Apso',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 11', 'metric': '25 - 28'},
 'id': 156,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Steady',
                 'Fearless',
                 'Friendly',
                 'Devoted',
                 'Assertive',
                 'Spirited',
                 'Energetic',
                 'Lively',
                 'Alert',
                 'Obedient',
                 'Playful',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '12 - 18', 'metric': '5 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970b4'),
 'bred_for': 'Lapdog',
 'breed': 'Maltese',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8 - 10', 'metric': '20 - 25'},
 'id': 161,
 'life_span': '15-18',
 'origin': [],
 'temperament': ['Playful',
                 'Docile',
                 'Fearless',
                 'Affectionate',
                 'Sweet-Tempered',
                 'Lively',
                 'Responsive',
                 'Easygoing',
                 'Gentle',
                 'Intelligent',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '4 - 7', 'metric': '2 - 3'}}
{'_id': ObjectId('67ed6529b16d68169fd970b5'),
 'bred_for': '',
 'breed': 'Miniature American Shepherd',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '13 - 18', 'metric': '33 - 46'},
 'id': 165,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Energetic', 'Loyal', 'Intelligent', 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 40', 'metric': '9 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd970b6'),
 'bred_for': 'Small vermin hunting',
 'breed': 'Miniature Pinscher',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 12.5', 'metric': '25 - 32'},
 'id': 167,
 'life_span': '15-15',
 'origin': [],
 'temperament': ['Clever',
                 'Outgoing',
                 'Friendly',
                 'Energetic',
                 'Responsive',
                 'Playful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '8 - 11', 'metric': '4 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970b7'),
 'bred_for': 'Ratting',
 'breed': 'Miniature Schnauzer',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '12 - 14', 'metric': '30 - 36'},
 'id': 168,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Fearless',
                 'Friendly',
                 'Spirited',
                 'Alert',
                 'Obedient',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '11 - 20', 'metric': '5 - 9'}}
{'_id': ObjectId('67ed6529b16d68169fd970b8'),
 'bred_for': 'All purpose water dog, fishing aid',
 'breed': 'Newfoundland',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '26 - 28', 'metric': '66 - 71'},
 'id': 171,
 'life_span': '8-10',
 'origin': [],
 'temperament': ['Sweet-Tempered', 'Gentle', 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '100 - 150', 'metric': '45 - 68'}}
{'_id': ObjectId('67ed6529b16d68169fd970b9'),
 'bred_for': 'Ratting, fox bolting',
 'breed': 'Norfolk Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9 - 10', 'metric': '23 - 25'},
 'id': 172,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Self-confidence',
                 'Fearless',
                 'Spirited',
                 'Companionable',
                 'Happy',
                 'Lovable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '11 - 12', 'metric': '5 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970ba'),
 'bred_for': 'Ratting, fox bolting',
 'breed': 'Norwich Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10', 'metric': '25'},
 'id': 176,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Hardy',
                 'Affectionate',
                 'Energetic',
                 'Sensitive',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '11 - 12', 'metric': '5 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970bb'),
 'bred_for': '',
 'breed': 'Nova Scotia Duck Tolling Retriever',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17 - 21', 'metric': '43 - 53'},
 'id': 177,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Outgoing', 'Alert', 'Patient', 'Intelligent', 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 50', 'metric': '16 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd970bc'),
 'bred_for': 'Driving sheep, cattle',
 'breed': 'Old English Sheepdog',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21', 'metric': '53'},
 'id': 178,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Sociable',
                 'Bubbly',
                 'Playful',
                 'Adaptable',
                 'Intelligent',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '60 - 100', 'metric': '27 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd970bd'),
 'bred_for': '',
 'breed': 'Olde English Bulldogge',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '15 - 19', 'metric': '38 - 48'},
 'id': 179,
 'life_span': '9-14',
 'origin': [],
 'temperament': ['Friendly',
                 'Alert',
                 'Confident',
                 'Loving',
                 'Courageous',
                 'Strong'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '65 – 85', 'metric': 'NaN'}}
{'_id': ObjectId('67ed6529b16d68169fd970be'),
 'bred_for': 'Lapdog',
 'breed': 'Papillon',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
 'id': 181,
 'life_span': '13-17',
 'origin': [],
 'temperament': ['Hardy',
                 'Friendly',
                 'Energetic',
                 'Alert',
                 'Intelligent',
                 'Happy'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '3 - 12', 'metric': '1 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970bf'),
 'bred_for': 'Lapdog',
 'breed': 'Pekingese',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '6 - 9', 'metric': '15 - 23'},
 'id': 183,
 'life_span': '14-18',
 'origin': [],
 'temperament': ['Opinionated',
                 'Good-natured',
                 'Stubborn',
                 'Affectionate',
                 'Aggressive',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '14', 'metric': '6'}}
{'_id': ObjectId('67ed6529b16d68169fd970c0'),
 'bred_for': 'Driving stock to market in northern Wales',
 'breed': 'Pembroke Welsh Corgi',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
 'id': 184,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Tenacious',
                 'Outgoing',
                 'Friendly',
                 'Bold',
                 'Playful',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 30', 'metric': '11 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970c1'),
 'bred_for': '',
 'breed': 'Perro de Presa Canario',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 25.5', 'metric': '56 - 65'},
 'id': 185,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Strong Willed', 'Suspicious', 'Gentle', 'Dominant', 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '88 - 110', 'metric': '40 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd970c2'),
 'bred_for': 'Hunting rabbits',
 'breed': 'Pharaoh Hound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21 - 25', 'metric': '53 - 64'},
 'id': 188,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Affectionate',
                 'Sociable',
                 'Playful',
                 'Intelligent',
                 'Active',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 60', 'metric': '18 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970c3'),
 'bred_for': 'Hunting big-game like Boar.',
 'breed': 'Plott',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 25', 'metric': '51 - 64'},
 'id': 189,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Bold', 'Alert', 'Loyal', 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '40 - 60', 'metric': '18 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970c4'),
 'bred_for': 'Companion',
 'breed': 'Pomeranian',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8 - 12', 'metric': '20 - 30'},
 'id': 193,
 'life_span': '15-15',
 'origin': [],
 'temperament': ['Extroverted',
                 'Friendly',
                 'Sociable',
                 'Playful',
                 'Intelligent',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '3 - 7', 'metric': '1 - 3'}}
{'_id': ObjectId('67ed6529b16d68169fd970c5'),
 'bred_for': '',
 'breed': 'Poodle (Miniature)',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '11 - 15', 'metric': '28 - 38'},
 'id': 196,
 'life_span': '12-15',
 'origin': [],
 'temperament': [''],
 'type_of_pet': 'dog',
 'weight': {'imperial': '15 - 17', 'metric': '7 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970c6'),
 'bred_for': '',
 'breed': 'Poodle (Toy)',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9 - 11', 'metric': '23 - 28'},
 'id': 197,
 'life_span': '18-18',
 'origin': [],
 'temperament': [''],
 'type_of_pet': 'dog',
 'weight': {'imperial': '6 - 9', 'metric': '3 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd970c7'),
 'bred_for': 'Lapdog',
 'breed': 'Pug',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
 'id': 201,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Docile',
                 'Clever',
                 'Charming',
                 'Stubborn',
                 'Sociable',
                 'Playful',
                 'Quiet',
                 'Attentive'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '14 - 18', 'metric': '6 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970c8'),
 'bred_for': 'Herding',
 'breed': 'Puli',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '16 - 17', 'metric': '41 - 43'},
 'id': 204,
 'life_span': '12-16',
 'origin': [],
 'temperament': ['Energetic',
                 'Agile',
                 'Loyal',
                 'Obedient',
                 'Intelligent',
                 'Faithful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 35', 'metric': '11 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd970c9'),
 'bred_for': '',
 'breed': 'Pumi',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '15 - 18.5', 'metric': '38 - 47'},
 'id': 205,
 'life_span': '13-15',
 'origin': [],
 'temperament': ['Lively',
                 'Reserved',
                 'Intelligent',
                 'Active',
                 'Protective',
                 'Vocal'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '18 - 33', 'metric': '8 - 15'}}
{'_id': ObjectId('67ed6529b16d68169fd970ca'),
 'bred_for': '',
 'breed': 'Rat Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 13', 'metric': '25 - 33'},
 'id': 207,
 'life_span': '12-18',
 'origin': [],
 'temperament': ['Affectionate',
                 'Lively',
                 'Inquisitive',
                 'Alert',
                 'Intelligent',
                 'Loving'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '8 - 25', 'metric': '4 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd970cb'),
 'bred_for': 'Hunting raccoon, deer, bear, and cougar.',
 'breed': 'Redbone Coonhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21 - 27', 'metric': '53 - 69'},
 'id': 208,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Affectionate',
                 'Energetic',
                 'Independent',
                 'Companionable',
                 'Familial',
                 'Unflappable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970cc'),
 'bred_for': 'Big game hunting, guarding',
 'breed': 'Rhodesian Ridgeback',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 27', 'metric': '61 - 69'},
 'id': 209,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Strong Willed',
                 'Mischievous',
                 'Loyal',
                 'Dignified',
                 'Sensitive',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '75 - 80', 'metric': '34 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970cd'),
 'bred_for': 'Cattle drover, guardian, draft',
 'breed': 'Rottweiler',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
 'id': 210,
 'life_span': '8-10',
 'origin': [],
 'temperament': ['Steady',
                 'Good-natured',
                 'Fearless',
                 'Devoted',
                 'Alert',
                 'Obedient',
                 'Confident',
                 'Self-assured',
                 'Calm',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '75 - 110', 'metric': '34 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd970ce'),
 'bred_for': '',
 'breed': 'Russian Toy',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '7.5 - 10.5', 'metric': '19 - 27'},
 'id': 211,
 'life_span': '10-12',
 'origin': [],
 'temperament': [''],
 'type_of_pet': 'dog',
 'weight': {'imperial': '3 - 6', 'metric': '1 - 3'}}
{'_id': ObjectId('67ed6529b16d68169fd970cf'),
 'bred_for': 'Draft, search, rescue',
 'breed': 'Saint Bernard',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '25.5 - 27.5', 'metric': '65 - 70'},
 'id': 212,
 'life_span': '7-10',
 'origin': [],
 'temperament': ['Friendly', 'Lively', 'Gentle', 'Watchful', 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '130 - 180', 'metric': '59 - 82'}}
{'_id': ObjectId('67ed6529b16d68169fd970d0'),
 'bred_for': 'Coursing gazelle and hare',
 'breed': 'Saluki',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 28', 'metric': '58 - 71'},
 'id': 213,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Aloof', 'Reserved', 'Intelligent', 'Quiet'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 65', 'metric': '16 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd970d1'),
 'bred_for': 'Herding reindeer, guardian, draft',
 'breed': 'Samoyed',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '19 - 23.5', 'metric': '48 - 60'},
 'id': 214,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Stubborn',
                 'Friendly',
                 'Sociable',
                 'Lively',
                 'Alert',
                 'Playful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 60', 'metric': '23 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970d2'),
 'bred_for': 'Barge watchdog',
 'breed': 'Schipperke',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 13', 'metric': '25 - 33'},
 'id': 216,
 'life_span': '13-15',
 'origin': [],
 'temperament': ['Fearless',
                 'Agile',
                 'Curious',
                 'Independent',
                 'Confident',
                 'Faithful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '10 - 16', 'metric': '5 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970d3'),
 'bred_for': 'Coursing deer',
 'breed': 'Scottish Deerhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '28 - 32', 'metric': '71 - 81'},
 'id': 218,
 'life_span': '8-10',
 'origin': [],
 'temperament': ['Docile', 'Friendly', 'Dignified', 'Gentle'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '70 - 130', 'metric': '32 - 59'}}
{'_id': ObjectId('67ed6529b16d68169fd970d4'),
 'bred_for': 'Vermin hunting',
 'breed': 'Scottish Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10', 'metric': '25'},
 'id': 219,
 'life_span': '11-13',
 'origin': [],
 'temperament': ['Feisty',
                 'Alert',
                 'Independent',
                 'Playful',
                 'Quick',
                 'Self-assured'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '18 - 22', 'metric': '8 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd970d5'),
 'bred_for': 'Sheep herding',
 'breed': 'Shetland Sheepdog',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '13 - 16', 'metric': '33 - 41'},
 'id': 221,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Affectionate',
                 'Lively',
                 'Responsive',
                 'Alert',
                 'Loyal',
                 'Reserved',
                 'Playful',
                 'Gentle',
                 'Intelligent',
                 'Active',
                 'Trainable',
                 'Strong'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30', 'metric': '14'}}
{'_id': ObjectId('67ed6529b16d68169fd970d6'),
 'bred_for': 'Hunting in the mountains of Japan, Alert Watchdog',
 'breed': 'Shiba Inu',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '13.5 - 16.5', 'metric': '34 - 42'},
 'id': 222,
 'life_span': '12-16',
 'origin': [],
 'temperament': ['Charming',
                 'Fearless',
                 'Keen',
                 'Alert',
                 'Confident',
                 'Faithful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '17 - 23', 'metric': '8 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd970d7'),
 'bred_for': 'Lapdog',
 'breed': 'Shih Tzu',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
 'id': 223,
 'life_span': '10-18',
 'origin': [],
 'temperament': ['Clever',
                 'Spunky',
                 'Outgoing',
                 'Friendly',
                 'Affectionate',
                 'Lively',
                 'Alert',
                 'Loyal',
                 'Independent',
                 'Playful',
                 'Gentle',
                 'Intelligent',
                 'Happy',
                 'Active',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '9 - 16', 'metric': '4 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970d8'),
 'bred_for': 'Swimming, Carrying backpacks, Pulling carts or sleds',
 'breed': 'Shiloh Shepherd',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '26 - 30', 'metric': '66 - 76'},
 'id': 225,
 'life_span': '9-14',
 'origin': [],
 'temperament': ['Outgoing',
                 'Loyal',
                 'Companionable',
                 'Gentle',
                 'Loving',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '120 - 140', 'metric': '54 - 64'}}
{'_id': ObjectId('67ed6529b16d68169fd970d9'),
 'bred_for': 'Sled pulling',
 'breed': 'Siberian Husky',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 23.5', 'metric': '51 - 60'},
 'id': 226,
 'life_span': '12-12',
 'origin': [],
 'temperament': ['Outgoing', 'Friendly', 'Alert', 'Gentle', 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 60', 'metric': '16 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970da'),
 'bred_for': 'Small vermin hunting, companionship',
 'breed': 'Silky Terrier',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '9 - 10', 'metric': '23 - 25'},
 'id': 228,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Friendly',
                 'Responsive',
                 'Inquisitive',
                 'Alert',
                 'Quick',
                 'Joyful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '8 - 10', 'metric': '4 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970db'),
 'bred_for': 'Fox bolting',
 'breed': 'Smooth Fox Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '15.5', 'metric': '39'},
 'id': 232,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Fearless',
                 'Affectionate',
                 'Alert',
                 'Playful',
                 'Intelligent',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': 'up - 18', 'metric': 'NaN - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970dc'),
 'bred_for': 'Vermin hunting, guarding, all-around farm helper',
 'breed': 'Soft Coated Wheaten Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '16 - 18', 'metric': '41 - 46'},
 'id': 233,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Affectionate',
                 'Spirited',
                 'Energetic',
                 'Playful',
                 'Intelligent',
                 'Faithful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30 - 40', 'metric': '14 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd970dd'),
 'bred_for': 'Herding flocks of sheep and goats from one pasture to another',
 'breed': 'Spanish Water Dog',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '16 - 20', 'metric': '41 - 51'},
 'id': 235,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Trainable',
                 'Diligent',
                 'Affectionate',
                 'Loyal',
                 'Athletic',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30 - 50', 'metric': '14 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd970de'),
 'bred_for': '',
 'breed': 'Spinone Italiano',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22.5 - 27.5', 'metric': '57 - 70'},
 'id': 236,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Docile',
                 'Friendly',
                 'Affectionate',
                 'Loyal',
                 'Patient',
                 'Gentle'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '61 - 85', 'metric': '28 - 39'}}
{'_id': ObjectId('67ed6529b16d68169fd970df'),
 'bred_for': '',
 'breed': 'Staffordshire Bull Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '14 - 16', 'metric': '36 - 41'},
 'id': 238,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Reliable',
                 'Fearless',
                 'Bold',
                 'Affectionate',
                 'Loyal',
                 'Intelligent',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '24 - 38', 'metric': '11 - 17'}}
{'_id': ObjectId('67ed6529b16d68169fd970e0'),
 'bred_for': 'Ratting, guarding',
 'breed': 'Standard Schnauzer',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17.5 - 19.5', 'metric': '44 - 50'},
 'id': 239,
 'life_span': '13-15',
 'origin': [],
 'temperament': ['Trainable',
                 'Good-natured',
                 'Devoted',
                 'Lively',
                 'Playful',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '30 - 50', 'metric': '14 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd970e1'),
 'bred_for': '',
 'breed': 'Swedish Vallhund',
 'breed_group': 'Herding',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '11.5 - 13.5', 'metric': '29 - 34'},
 'id': 242,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Fearless',
                 'Friendly',
                 'Energetic',
                 'Alert',
                 'Intelligent',
                 'Watchful'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970e2'),
 'bred_for': '',
 'breed': 'Thai Ridgeback',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 24', 'metric': '51 - 61'},
 'id': 243,
 'life_span': '10-12',
 'origin': [],
 'temperament': ['Protective',
                 'Loyal',
                 'Independent',
                 'Intelligent',
                 'Loving',
                 'Familial'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 55', 'metric': '16 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd970e3'),
 'bred_for': '',
 'breed': 'Tibetan Mastiff',
 'breed_group': 'Working',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '24 - 26', 'metric': '61 - 66'},
 'id': 244,
 'life_span': '10-14',
 'origin': [],
 'temperament': ['Strong Willed',
                 'Tenacious',
                 'Aloof',
                 'Stubborn',
                 'Intelligent',
                 'Protective'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '85 - 140', 'metric': '39 - 64'}}
{'_id': ObjectId('67ed6529b16d68169fd970e4'),
 'bred_for': '',
 'breed': 'Tibetan Spaniel',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10', 'metric': '25'},
 'id': 245,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Willful',
                 'Aloof',
                 'Assertive',
                 'Independent',
                 'Playful',
                 'Intelligent',
                 'Happy'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '9 - 15', 'metric': '4 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970e5'),
 'bred_for': 'Good luck charms, mascots, watchdogs, herding dogs, and '
             'companions',
 'breed': 'Tibetan Terrier',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '14 - 17', 'metric': '36 - 43'},
 'id': 246,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Affectionate',
                 'Energetic',
                 'Amiable',
                 'Reserved',
                 'Gentle',
                 'Sensitive'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '20 - 24', 'metric': '9 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd970e6'),
 'bred_for': '',
 'breed': 'Toy Fox Terrier',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
 'id': 248,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Friendly',
                 'Spirited',
                 'Alert',
                 'Loyal',
                 'Playful',
                 'Intelligent'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '4 - 9', 'metric': '2 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd970e7'),
 'bred_for': '',
 'breed': 'Treeing Walker Coonhound',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 27', 'metric': '51 - 69'},
 'id': 250,
 'life_span': '10-13',
 'origin': [],
 'temperament': ['Clever',
                 'Affectionate',
                 'Confident',
                 'Intelligent',
                 'Loving',
                 'Trainable'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970e8'),
 'bred_for': 'Pointing and trailing',
 'breed': 'Vizsla',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21 - 24', 'metric': '53 - 61'},
 'id': 251,
 'life_span': '10-14',
 'origin': [],
 'temperament': ['Affectionate', 'Energetic', 'Loyal', 'Gentle', 'Quiet'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '50 - 65', 'metric': '23 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd970e9'),
 'bred_for': 'Large game trailing and versatile gundog',
 'breed': 'Weimaraner',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
 'id': 253,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Steady',
                 'Aloof',
                 'Stubborn',
                 'Energetic',
                 'Alert',
                 'Intelligent',
                 'Powerful',
                 'Fast'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '55 - 90', 'metric': '25 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd970ea'),
 'bred_for': 'Flushing and retrieving birds',
 'breed': 'Welsh Springer Spaniel',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '17 - 19', 'metric': '43 - 48'},
 'id': 254,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Stubborn',
                 'Friendly',
                 'Affectionate',
                 'Loyal',
                 'Playful',
                 'Active'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '35 - 55', 'metric': '16 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd970eb'),
 'bred_for': 'Fox, badger, vermin hunting',
 'breed': 'West Highland White Terrier',
 'breed_group': 'Terrier',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 11', 'metric': '25 - 28'},
 'id': 256,
 'life_span': '15-20',
 'origin': [],
 'temperament': ['Hardy',
                 'Friendly',
                 'Alert',
                 'Independent',
                 'Gay',
                 'Active',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '15 - 22', 'metric': '7 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd970ec'),
 'bred_for': 'Coursing, racing',
 'breed': 'Whippet',
 'breed_group': 'Hound',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '18 - 22', 'metric': '46 - 56'},
 'id': 257,
 'life_span': '12-15',
 'origin': [],
 'temperament': ['Friendly',
                 'Affectionate',
                 'Lively',
                 'Gentle',
                 'Intelligent',
                 'Quiet'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '25 - 35', 'metric': '11 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd970ed'),
 'bred_for': '',
 'breed': 'White Shepherd',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '22 - 25', 'metric': '56 - 64'},
 'id': 258,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Self-confidence',
                 'Aloof',
                 'Fearless',
                 'Alert',
                 'Companionable',
                 'Eager'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '60 - 85', 'metric': '27 - 39'}}
{'_id': ObjectId('67ed6529b16d68169fd970ee'),
 'bred_for': 'Vermin hunting, fox bolting',
 'breed': 'Wire Fox Terrier',
 'breed_group': '',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '13 - 16', 'metric': '33 - 41'},
 'id': 259,
 'life_span': '13-14',
 'origin': [],
 'temperament': ['Fearless', 'Friendly', 'Bold', 'Keen', 'Alert', 'Quick'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '15 - 19', 'metric': '7 - 9'}}
{'_id': ObjectId('67ed6529b16d68169fd970ef'),
 'bred_for': 'Gundog, "swamp-tromping", Flushing, pointing, and retrieving '
             'water fowl & game birds',
 'breed': 'Wirehaired Pointing Griffon',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '20 - 24', 'metric': '51 - 61'},
 'id': 260,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Loyal', 'Gentle', 'Vigilant', 'Trainable', 'Proud'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 70', 'metric': '20 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd970f0'),
 'bred_for': '',
 'breed': 'Wirehaired Vizsla',
 'breed_group': 'Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '21.5 - 25', 'metric': '55 - 64'},
 'id': 261,
 'life_span': '12-14',
 'origin': [],
 'temperament': [''],
 'type_of_pet': 'dog',
 'weight': {'imperial': '45 - 65', 'metric': '20 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd970f1'),
 'bred_for': '',
 'breed': 'Xoloitzcuintli',
 'breed_group': 'Non-Sporting',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '10 - 23', 'metric': '25 - 58'},
 'id': 262,
 'life_span': '12-14',
 'origin': [],
 'temperament': ['Cheerful',
                 'Alert',
                 'Companionable',
                 'Intelligent',
                 'Protective',
                 'Calm'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '9 - 31', 'metric': '4 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970f2'),
 'bred_for': 'Small vermin hunting',
 'breed': 'Yorkshire Terrier',
 'breed_group': 'Toy',
 'country_code': '',
 'geocord': '',
 'height': {'imperial': '8 - 9', 'metric': '20 - 23'},
 'id': 264,
 'life_span': '12-16',
 'origin': [],
 'temperament': ['Bold',
                 'Independent',
                 'Confident',
                 'Intelligent',
                 'Courageous'],
 'type_of_pet': 'dog',
 'weight': {'imperial': '4 - 7', 'metric': '2 - 3'}}

Selection of specific columns for better understanding of dataset

InĀ [63]:
db = client["dogsdb"]
collection = db["type_dogs"]

# Query the collection with a projection and limit to 5 results
cursor = collection.find(
    {}, 
    {
        "_id": 0,
        "type_of_pet": 1,
        "breed": 1,
        "country_code": 1,
        "origin": 1,
        "geocord": 1,
        "life_span": 1,
        "weight": 1,
        "temperament": 1,
        "height": 1,
        "breed_group": 1
    }
).limit(10)

# Convert the cursor to a list, then create a DataFrame
data = list(cursor)
df = pd.DataFrame(data)
df
Out[63]:
type_of_pet breed origin country_code life_span temperament weight height breed_group geocord
0 dog Affenpinscher [Germany, France] 10-12 [Stubborn, Curious, Playful, Adventurous, Acti... {'imperial': '6 - 13', 'metric': '3 - 6'} {'imperial': '9 - 11.5', 'metric': '23 - 29'} Toy {'lat': 51.1638175, 'lon': 10.4478313}
1 dog Afghan Hound [Afghanistan, Iran, Pakistan] AG 10-13 [Aloof, Clownish, Dignified, Independent, Happy] {'imperial': '50 - 60', 'metric': '23 - 27'} {'imperial': '25 - 27', 'metric': '64 - 69'} Hound {'lat': 33.7680065, 'lon': 66.2385139}
2 dog African Hunting Dog [] 11-11 [Wild, Hardworking, Dutiful] {'imperial': '44 - 66', 'metric': '20 - 30'} {'imperial': '30', 'metric': '76'}
3 dog Airedale Terrier [United Kingdom, England] 10-13 [Outgoing, Friendly, Alert, Confident, Intelli... {'imperial': '40 - 65', 'metric': '18 - 29'} {'imperial': '21 - 23', 'metric': '53 - 58'} Terrier {'lat': 54.7023545, 'lon': -3.2765753}
4 dog Akbash Dog [] 10-12 [Loyal, Independent, Intelligent, Brave] {'imperial': '90 - 120', 'metric': '41 - 54'} {'imperial': '28 - 34', 'metric': '71 - 86'} Working
5 dog Akita [] 10-14 [Docile, Alert, Responsive, Dignified, Compose... {'imperial': '65 - 115', 'metric': '29 - 52'} {'imperial': '24 - 28', 'metric': '61 - 71'} Working
6 dog Alapaha Blue Blood Bulldog [] 12-13 [Loving, Protective, Trainable, Dutiful, Respo... {'imperial': '55 - 90', 'metric': '25 - 41'} {'imperial': '18 - 24', 'metric': '46 - 61'} Mixed
7 dog Alaskan Husky [] 10-13 [Friendly, Energetic, Loyal, Gentle, Confident] {'imperial': '38 - 50', 'metric': '17 - 23'} {'imperial': '23 - 26', 'metric': '58 - 66'} Mixed
8 dog Alaskan Malamute [] 12-15 [Friendly, Affectionate, Devoted, Loyal, Digni... {'imperial': '65 - 100', 'metric': '29 - 45'} {'imperial': '23 - 25', 'metric': '58 - 64'} Working
9 dog American Bulldog [] 10-12 [Friendly, Assertive, Energetic, Loyal, Gentle... {'imperial': '60 - 120', 'metric': '27 - 54'} {'imperial': '22 - 27', 'metric': '56 - 69'} Working
InĀ [64]:
db = client["catsdb"]
collection = db["type_cats"]

for pet in collection.find():
    origin_field = pet.get("origin")

    if not origin_field:
        # Skip documents with no origin
        continue

    # If origin is a single string but may contain commas, split on the first comma
    if isinstance(origin_field, str):
        origin_field = origin_field.split(",")[0].strip()

    # Query Nominatim for just this first origin
    url = "https://nominatim.openstreetmap.org/search"
    params = {
        "country": origin_field,
        "format": "json"
    }
    headers = {
        "User-Agent": "MyAwesomeApp/1.0 (myemail@example.com)"
    }

    try:
        response = requests.get(url, params=params, headers=headers, timeout=10)
        response.raise_for_status()
        data = response.json()
    except requests.RequestException as e:
        print(f"Request failed for origin '{origin_field}': {e}")
        continue

    # Update if the data list is not empty
    if data:
        try:
            lat = float(data[0].get("lat", 0))
            lon = float(data[0].get("lon", 0))

            result = collection.update_one(
                {"_id": pet["_id"]},
                {"$set": {"geocord": {"lat": lat, "lon": lon}}}
            )

            if result.matched_count > 0:
                print(f"Updated doc _id={pet['_id']} with lat={lat}, lon={lon}")
            else:
                print(f"No document matched for _id={pet['_id']}")
        except (ValueError, KeyError) as e:
            print(f"Failed to parse lat/lon for origin '{origin_field}': {e}")
    else:
        print(f"No results for origin '{origin_field}'")

    time.sleep(1)

# Optional: Confirm an example
check_pet = collection.find_one({"_id": pet["_id"]})
print("Example updated pet with geocord:", check_pet.get("geocord"))
Updated doc _id=67ed652ab16d68169fd97122 with lat=39.7837304, lon=-100.445882
No results for origin '['Iran (Persia)']'
Updated doc _id=67ed652ab16d68169fd97124 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97125 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97126 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97127 with lat=64.6863136, lon=97.7453061
Updated doc _id=67ed652ab16d68169fd97128 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97129 with lat=54.7023545, lon=-3.2765753
Updated doc _id=67ed652ab16d68169fd9712a with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd9712b with lat=14.8971921, lon=100.83273
Updated doc _id=67ed652ab16d68169fd9712c with lat=64.6863136, lon=97.7453061
Updated doc _id=67ed652ab16d68169fd9712d with lat=1.357107, lon=103.8194992
Updated doc _id=67ed652ab16d68169fd9712e with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd9712f with lat=8.3676771, lon=49.083416
Updated doc _id=67ed652ab16d68169fd97130 with lat=61.0666922, lon=-107.991707
Updated doc _id=67ed652ab16d68169fd97131 with lat=61.0666922, lon=-107.991707
Updated doc _id=67ed652ab16d68169fd97132 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97133 with lat=39.294076, lon=35.2316631
Updated doc _id=67ed652ab16d68169fd97134 with lat=39.294076, lon=35.2316631
Updated doc _id=67ed652ab16d68169fd97135 with lat=39.7837304, lon=-100.445882
Example updated pet with geocord: {'lat': 39.7837304, 'lon': -100.445882}

Extracting origin from from type_cats collection, and adding coordinates to empty column 'geocord'¶

Selection of specific columns for better understanding of dataset¶

InĀ [Ā ]:
db = client["catsdb"]
collection = db["type_cats"]

# Query the collection with a projection
pipeline = collection.find(
    {}, 
    {
        "_id": 0,
        "type_of_pet": 1,
        "breed": 1,
        "country_code": 1,
        "origin": 1,
        "geocord": 1,
        "life_span": 1,
        "weight": 1,
        "temperament": 1
    }
).limit(5)

# Convert the pipeline to a list, then create a DataFrame
data = list(pipeline)
df = pd.DataFrame(data)
df

šŸ“Š Data Analysis¶

🐶 Dogs Database Collection¶

This section explores and analyzes the data stored in the type_dogs collection.

Key areas of focus include:

  • Breed distribution
  • Temperament traits
  • Height and weight analysis
  • Breed group statistics
  • Geographic origin insights

Using aggregation pipelines and visualizations, we extract meaningful patterns and trends from the dataset.

To get the unique values of breed_group from your MongoDB collection, we can use the .distinct() method in PyMongo

🧠 Intelligent Dog Breeds in the Sporting Group¶

This MongoDB aggregation pipeline retrieves dog breeds that are part of the Sporting group and have the "Intelligent" temperament.

🧩 Pipeline Breakdown¶

  1. $match

    • Filters documents to include only those where:
      • "breed_group" is "Sporting"
      • "temperament" array contains the string "Intelligent"
  2. $project

    • Returns only selected fields:
      • breed
      • breed_group
      • temperament
    • Excludes the default _id field from the output.

šŸ“‹ Output¶

The result is a list of breeds that:

  • Belong to the Sporting group, which includes active and energetic breeds often used for hunting or retrieving.
  • Are described as Intelligent, suggesting quick learning and trainability.

This filtered list is useful for identifying smart, athletic dog breeds suited for active owners or working roles.

InĀ [Ā ]:
import pandas as pd

db = client["dogsdb"]
collection = db["type_dogs"]

pipeline = [
    {
        "$match": {
            "breed_group": "Sporting",
            "temperament": { "$regex": "Intelligent", "$options": "i" }
        }
    },
    {
        "$project": {
            "_id": 0,
            "breed_group": 1,
            "breed": 1,
            "temperament": 1
        }
    }
]

# Execute the aggregation pipeline
results = list(collection.aggregate(pipeline))
df1 = pd.DataFrame(results)
df1.head(6)
InĀ [Ā ]:
from wordcloud import WordCloud
import pandas as pd
import matplotlib.pyplot as plt

# Convert the results to a DataFrame
df1 = pd.DataFrame(results)

# Combine all breed names into a single string, separated by space
text = " ".join(df1['breed'].dropna().tolist())

# Create and display the word cloud
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)

plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud of Intelligent Breed Group Sporting')
plt.show()

šŸŽÆ Filtered List of Intelligent Sporting Breeds (Excluding Lapdogs)¶

This MongoDB aggregation pipeline is used to filter and display Sporting dog breeds that are known for being Intelligent, while specifically excluding those bred to be lapdogs.

šŸ” Pipeline Breakdown¶

  1. $match

    • Filters documents where:
      • breed_group is "Sporting"
      • temperament includes "Intelligent" (searches within the array)
      • bred_for does not contain the word "lapdog" (case-insensitive exclusion using $not with $regex)
  2. $project

    • Selects and returns only the following fields:
      • breed
      • breed_group
      • temperament
      • bred_for
    • Omits the default _id field from the output.

šŸ“‹ Output¶

The result is a curated list of breeds that:

  • Belong to the Sporting group
  • Are described as Intelligent
  • Were not bred to be lapdogs

This helps narrow down active, intelligent breeds that are typically used for tasks like hunting, retrieving, or field work — not just companionship.

InĀ [Ā ]:
import pandas as pd

db = client["dogsdb"]
pets_collection = db["type_dogs"]

# Aggregation pipeline
pipeline = [
    {
        "$match": {
            "breed_group": "Sporting",
            "temperament": "Intelligent",
            "bred_for": {
                "$not": {
                    "$regex": "lapdog",
                    "$options": "i"  
                }
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "breed_group": 1,
            "breed": 1,
            "temperament": 1,
            "bred_for": 1
        }
    }
]

# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df2 = pd.DataFrame(results)

# Display the first 6 results
df2.head(6)
InĀ [Ā ]:
from wordcloud import WordCloud
import pandas as pd
import matplotlib.pyplot as plt

# Convert the results to a DataFrame
df2 = pd.DataFrame(results)

# Combine all breed names into a single string, separated by space
text = " ".join(df2['breed'].dropna().tolist())

# Create and display the word cloud
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)

plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud of Intelligent Breed Group Sporting')
plt.show()

🐶 Top 10 Tallest Dog Breeds by Average Metric Height¶

This MongoDB aggregation pipeline retrieves the top 10 tallest dog breeds based on their average height in centimeters (height.metric field).

šŸ”„ Pipeline Breakdown¶

  1. $project

    • Extracts the breed field.
    • Calculates a new field avgMetricHeight:
      • Splits the string in height.metric (e.g., "23 - 29") into two values: ["23", "29"].
      • Converts them to numbers ($toDouble).
      • Averages the two numbers using $avg.
  2. $sort

    • Sorts all documents in descending order of avgMetricHeight.
  3. $limit

    • Limits the results to the top 10 breeds with the highest average height.

šŸ“Š Output¶

The result is a list of dog breeds and their respective average heights in metric units (cm), sorted from tallest to shortest.

Use this pipeline to quickly identify the largest breeds based on standardized height data!

InĀ [Ā ]:
from pymongo import MongoClient
import matplotlib.pyplot as plt
import numpy as np

db = client["dogsdb"]
collection = db["type_dogs"]

# Define the aggregation pipeline with $limit
pipeline = [
    {
        "$project": {
            "breed": 1,
            "avgMetricHeight": {
                "$avg": {
                    "$map": {
                        "input": { "$split": ["$height.metric", " - "] },
                        "as": "h",
                        "in": { "$toDouble": "$$h" }
                    }
                }
            }
        }
    },
    {
        "$sort": { "avgMetricHeight": -1 }
    },
    {
        "$limit": 10
    }
]


# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df3 = pd.DataFrame(results)

# Display the first 10 results
df3.head(10)
InĀ [Ā ]:
# Extract data for plotting
breeds = [doc["breed"] for doc in results]
avg_heights = [doc["avgMetricHeight"] for doc in results]

# Prepare numeric y-axis for horizontal bar chart
y = np.arange(len(breeds))
colors = plt.cm.plasma(np.linspace(0, 1, len(breeds)))

# Create the horizontal bar chart
plt.figure(figsize=(10, 6))
plt.barh(y, avg_heights, color=colors)
plt.xlabel("Average Metric Height in cm")
plt.ylabel("Breed")
plt.title("Top 10 Tallest Dog Breeds by Average Metric Height")
plt.yticks(y, breeds)
plt.gca().invert_yaxis()
plt.tight_layout()
plt.show()

āš–ļø Average Metric Weight by Dog Breed¶

This aggregation pipeline calculates and sorts dog breeds by their average weight (in kilograms) based on the weight.metric field.

šŸ” Pipeline Breakdown¶

  1. $project

    • Keeps the breed field.
    • Creates avgMetricWeight by:
      • Splitting the string in weight.metric (e.g., "3 - 6") into a list: ["3", "6"]
      • Converting the values to numbers
      • Calculating the average using $avg
  2. $sort

    • Sorts breeds in descending order by their avgMetricWeight

This helps identify the heaviest dog breeds based on average weight data.

InĀ [Ā ]:
# Define the aggregation pipeline
db = client["dogsdb"]
collection = db["type_dogs"]

# Define the aggregation pipeline with $limit
pipeline = [
    {
        "$project": {
            "breed": 1,
            "avgMetricWeight": {
                "$avg": {
                    "$map": {
                        "input": { "$split": ["$weight.metric", " - "] },
                        "as": "w",
                        "in": { "$toDouble": "$$w" }
                    }
                }
            }
        }
    },
    {
        "$sort": { "avgMetricWeight": -1 }
    },
    {
        "$limit": 20
    }
]

# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df4 = pd.DataFrame(results)

# Display the first 10 results
df4.head(10)
InĀ [Ā ]:
# Extract data
breeds = [doc["breed"] for doc in results]
avg_weights = [doc["avgMetricWeight"] for doc in results]

# Prepare x-axis
x = np.arange(len(breeds))
colors = plt.cm.viridis(np.linspace(0, 1, len(breeds)))

# Create bar chart
plt.figure(figsize=(10, 6))
plt.bar(x, avg_weights, color=colors)
plt.xlabel("Breed")
plt.ylabel("Average Metric Weight in Kg")
plt.title("Top 20 Dog Breeds by Average Metric Weight")
plt.xticks(x, breeds, rotation=45, ha="right")
plt.tight_layout()
plt.show()

šŸ• Longevity Analysis: Dog Breeds with Long Life Expectancy¶

This pipeline filters dog breeds based on their upper life span, identifying breeds that typically live 13 years or more.

🧩 Pipeline Breakdown¶

  1. $project

    • Keeps breed and life_span fields.
    • Creates a new field lifeSpanBounds by:
      • Splitting the life_span string (e.g., "10-12") by "-" into a list.
      • Trimming whitespace from the resulting parts.
  2. Second $project

    • Calculates upperLifeSpan:
      • If the life span has a range (e.g., ["10", "12"]), the second value is used.
      • If it’s a single number (e.g., "14"), it uses that directly.
  3. $match

    • Filters only the breeds where upperLifeSpan is 13 or greater.

šŸ“‹ Result¶

A refined list of dog breeds with relatively long life expectancy, useful for:

  • Understanding breed longevity
  • Informing adopters and pet owners
  • Enriching data visualizations and statistics on dog health
InĀ [Ā ]:
# 1) Run the pipeline and convert results to a list
pipeline = [
    {
        "$project": {
            "breed": 1,
            "life_span": 1,
            "cleanLifeSpan": {
                "$replaceAll": {
                    "input": {
                        "$replaceAll": {
                            "input": "$life_span",
                            "find": " years",
                            "replacement": ""
                        }
                    },
                    "find": "-",
                    "replacement": " - "
                }
            }
        }
    },
    {
        "$project": {
            "breed": 1,
            "lifeSpanBounds": {
                "$map": {
                    "input": { "$split": ["$cleanLifeSpan", " - "] },
                    "as": "bound",
                    "in": { "$trim": { "input": "$$bound" } }
                }
            }
        }
    },
    {
        "$project": {
            "breed": 1,
            "upperLifeSpan": {
                "$cond": [
                    { "$gte": [{ "$size": "$lifeSpanBounds" }, 2] },
                    { "$toDouble": { "$arrayElemAt": ["$lifeSpanBounds", 1] } },
                    { "$toDouble": { "$arrayElemAt": ["$lifeSpanBounds", 0] } }
                ]
            }
        }
    },
    {
        "$match": {
            "upperLifeSpan": { "$gte": 13 }
        }
    },
    {
        "$sort": { "upperLifeSpan": -1 }
    },
    {
        "$limit": 10
    }
]

# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df5 = pd.DataFrame(results)

# Display the first 10 results
df5.head(10)
InĀ [Ā ]:
import matplotlib.pyplot as plt

# Sort the correct DataFrame
df5_sorted = df5.sort_values(by="upperLifeSpan", ascending=False)

# Extract data for plotting
breeds = df5_sorted["breed"]
lifespans = df5_sorted["upperLifeSpan"]

# Create the plot
plt.figure(figsize=(10, 6))
plt.barh(breeds, lifespans, color=plt.cm.Paired.colors)
plt.xlabel("Upper Life Span (Years)")
plt.title("Top 10 Longest-Living Dog Breeds")
plt.gca().invert_yaxis()  # Highest lifespan on top
plt.tight_layout()
plt.show()

šŸ“š Breed Group Distribution¶

This aggregation pipeline provides a summary count of dog breeds by breed group.

šŸ” Pipeline Steps¶

  1. $group
    • Groups documents by the breed_group field.
    • Calculates the total number of breeds in each group using "$sum": 1.

šŸ“‹ Result¶

Returns a list of breed groups (e.g., "Sporting", "Toy", "Hound") along with the number of breeds in each group.

This summary helps understand the distribution of breeds across different functional or historical classifications.

InĀ [Ā ]:
pipeline = [
    {
        "$group": {
            "_id": "$breed_group",
            "count": {"$sum": 1}
        }
    }
]

# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df5 = pd.DataFrame(results)

# Display the first 10 results
df5.head(10)
InĀ [Ā ]:
# Extract the labels (breed groups) and sizes (counts)
labels = [doc["_id"] for doc in results if doc["_id"] is not None]
sizes = [doc["count"] for doc in results if doc["_id"] is not None]

# Plot the pie chart
plt.figure(figsize=(8, 8))
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
plt.title("Distribution of Dog Breed Groups")
plt.axis('equal')  # Equal aspect ratio ensures the pie chart is circular.
plt.show()

šŸŒ Visualization: Cat Breeds by Geographic Origin¶

This interactive map displays various cat breeds according to their country of origin, using geocoordinates stored in the type_cats collection.

šŸ” Steps Involved:¶

  1. MongoDB Query
    Retrieves breed data, origin, life span, weight, temperament, and geo-coordinates.

  2. Data Cleaning

    • Extracts lat and lon from the nested geocord field.
    • Converts origin from a list to a readable string format.
  3. Map Visualization (Plotly)

    • Each breed is shown as a dot on the map.
    • Hovering reveals breed name and country of origin.
    • Colored by origin for easy visual grouping.

šŸ—ŗļø Outcome¶

An interactive scatter map that provides insights into the geographic distribution of cat breeds globally.

InĀ [Ā ]:
import plotly.express as px

db = client["catsdb"]
collection = db["type_cats"]

# 2. Query the collection
cursor = collection.find(
    {}, 
    {
        "_id": 0,
        "type_of_pet": 1,
        "breed": 1,
        "country_code": 1,
        "origin": 1,
        "geocord": 1,
        "life_span": 1,
        "weight": 1,
        "temperament": 1
    }
)

results = collection.aggregate(pipeline)
for doc in results:
    print(doc)

df = pd.DataFrame(list(cursor))

# 3. Flatten geocord into 'lat' and 'lon'
df_geo = pd.json_normalize(df["geocord"])
df["lat"] = df_geo["lat"]
df["lon"] = df_geo["lon"]

# 4. Convert 'origin' from list to simple string 
def list_to_str(x):
    if isinstance(x, list) and len(x) > 0:
        return x[0]   # e.g. ["Egypt"] -> "Egypt"
    return "Unknown"

df["origin_str"] = df["origin"].apply(list_to_str)

fig = px.scatter_mapbox(
    df,
    lat="lat",
    lon="lon",
    hover_name="breed",
    hover_data=["origin_str"],
    color="origin_str",
    zoom=1,
    height=600
)

fig.update_layout(
    mapbox_style="open-street-map",
    title="Cat Breeds by Origin",
    title_x=0.5
)
fig.show()

pic4.jpeg

šŸŒŽ Origin Distribution of Cat Breeds¶

This aggregation pipeline analyzes how cat breeds are distributed across different countries of origin in the type_cats collection.

🧩 Pipeline Breakdown¶

  1. Group by Origin
    Counts how many cat breeds are associated with each origin.

  2. Calculate Total
    Gathers all origin counts into an array and computes the overall total.

  3. Unwind Origins
    Flattens the array to work with individual origin entries.

  4. Project Final Output
    Displays:

    • origin
    • count of breeds from that origin
    • proportion relative to the total number of breeds
  5. Sort by Proportion
    Orders the results from the most common to the least represented origins.

šŸ“Š Result¶

A ranked list of cat breed origins, showing their share of the total breed count, useful for visualizations like bar or pie charts.

InĀ [Ā ]:
import plotly.express as px

db = client["catsdb"]
collection = db["type_cats"]

pipeline = [
    # Group by "origin" and count the number of cats per origin
    {
        "$group": {
            "_id": "$origin",
            "count": {"$sum": 1}
        }
    },
    # Compute the total count and push each origin's count into an array
    {
        "$group": {
            "_id": None,
            "origins": {"$push": {"origin": "$_id", "count": "$count"}},
            "total": {"$sum": "$count"}
        }
    },
    # Unwind the origins array to get individual documents per origin
    {
        "$unwind": "$origins"
    },
    # Project the results: show the origin, count, and proportion (count divided by total)
    {
        "$project": {
            "_id": 0,
            "origin": "$origins.origin",
            "count": "$origins.count",
            "proportion": {"$divide": ["$origins.count", "$total"]}
        }
    },
    # Sort the results by proportion in descending order
    {
        "$sort": {"proportion": -1}
    },
    # Limit to top 10
    {
        "$limit": 10
    }
]

# Run the pipeline and convert the results to a list of dictionaries
data = list(collection.aggregate(pipeline))

# Convert the results into a pandas DataFrame
df = pd.DataFrame(data)

# Convert any list-type values in 'origin' to a comma-separated string
df['origin'] = df['origin'].apply(lambda x: ', '.join(x) if isinstance(x, list) else x)

# Create an interactive treemap using Plotly Express
fig = px.treemap(
    df,
    path=['origin'],  # Use origin as the hierarchical path
    values='count',   # Size corresponds to the count
    title='Cats Distribution by Origin'
)

# Update traces to show percentage on the plot using the computed percentEntry
fig.update_traces(
    texttemplate='%{label}<br>%{value} cats<br>%{percentEntry:.1%}',
)

# Display the plot
fig.show()
    

pic5.jpg

🐱🐶 Top 10 Longest-Living Cat and Dog Breeds¶

These pipelines to extract and analyze the average life span of cat and dog breeds.

  • Extracts numeric values using regex
  • Computes the average lifespan for each breed
  • Sorts by longest-living breeds
  • Displays the Top 10 cat breeds and Top 10 dog breeds

Useful for identifying breeds with the longest expected lifespans!

InĀ [Ā ]:
# === CATS PIPELINE ===
cat_collection = client["catsdb"]["type_cats"]

cat_pipeline = [
    { "$project": {
        "breed": 1,
        "life_span": 1,
        "type_of_pet": { "$literal": "cat" }
    }},
    { "$addFields": {
        "digits": {
            "$regexFindAll": {
                "input": { "$replaceAll": { "input": "$life_span", "find": "to", "replacement": "-" } },
                "regex": "\\d+"
            }
        }
    }},
    { "$addFields": {
        "numbers": {
            "$map": {
                "input": "$digits",
                "as": "d",
                "in": { "$toInt": "$$d.match" }
            }
        }
    }},
    { "$addFields": {
        "avgLifeSpan": {
            "$cond": [
                { "$eq": [ { "$size": "$numbers" }, 2 ] },
                { "$floor": { "$avg": "$numbers" } },
                { "$arrayElemAt": [ "$numbers", 0 ] }
            ]
        }
    }},
    { "$sort": { "avgLifeSpan": -1 } },
    { "$limit": 10 }
]

top_10_cats = list(cat_collection.aggregate(cat_pipeline))


# === DOGS PIPELINE ===
dog_collection = client["dogsdb"]["type_dogs"]

dog_pipeline = [
    { "$project": {
        "breed": 1,
        "life_span": 1,
        "type_of_pet": { "$literal": "dog" }
    }},
    { "$addFields": {
        "digits": {
            "$regexFindAll": {
                "input": { "$replaceAll": { "input": "$life_span", "find": "to", "replacement": "-" } },
                "regex": "\\d+"
            }
        }
    }},
    { "$addFields": {
        "numbers": {
            "$map": {
                "input": "$digits",
                "as": "d",
                "in": { "$toInt": "$$d.match" }
            }
        }
    }},
    { "$addFields": {
        "avgLifeSpan": {
            "$cond": [
                { "$eq": [ { "$size": "$numbers" }, 2 ] },
                { "$floor": { "$avg": "$numbers" } },
                { "$arrayElemAt": [ "$numbers", 0 ] }
            ]
        }
    }},
    { "$sort": { "avgLifeSpan": -1 } },
    { "$limit": 10 }
]

top_10_dogs = list(dog_collection.aggregate(dog_pipeline))


# === COMBINE & DISPLAY ===
print("\n🐱 Top 10 Longest-Living Cats:")
for cat in top_10_cats:
    print(f"- {cat['breed']}: {cat['avgLifeSpan']} years (raw: {cat.get('life_span')})")

print("\n🐶 Top 10 Longest-Living Dogs:")
for dog in top_10_dogs:
    print(f"- {dog['breed']}: {dog['avgLifeSpan']} years (raw: {dog.get('life_span')})")

# OPTIONAL: Combine into one list if needed
# Combine both lists
all_top_pets = top_10_cats + top_10_dogs

# Convert to pandas DataFrame
df_top_pets = pd.DataFrame(all_top_pets)

# Reorder columns if desired
df_top_pets = df_top_pets[["type_of_pet", "breed", "avgLifeSpan", "life_span"]]

# Display the DataFrame
df_top_pets

Conclusion¶

In this project, I explored the use of NoSQL databases and API integrations to efficiently store, retrieve, and analyze unstructured data. Using a NoSQL database gave me the flexibility to work with different types of data without being limited by a fixed schema, which was really useful for handling real world scenarios. I also connected to external APIs to bring in data dynamically, which added a real time component to the project. This combination of NoSQL and APIs helped me build a scalable and flexible data pipeline that could handle both live and batch data. Overall, this experience showed me how powerful and versatile these modern tools can be when used together.

Learning¶

Throughout this project, I gained hands on experience working with NoSQL databases and saw firsthand how they offer more flexibility and scalability than traditional relational databases, especially when working with varied or evolving data. I also learned how to connect and interact with APIs to fetch and update data in real time, which added a dynamic layer to my analysis. This helped me understand how to combine external data sources with local storage in an efficient and practical way. Working through this process improved my ability to design and implement end to end data workflows. These are skills I know will be valuable in future data projects.

InĀ [Ā ]:
!jupyter nbconvert final_project.ipynb --to html \
  --TagRemovePreprocessor.enabled=True \
  --TagRemovePreprocessor.remove_input_tags='["hide_input"]' \
  #--TagRemovePreprocessor.remove_single_output_tags='["remove_single_output"]'
InĀ [Ā ]:
!jupyter nbconvert final_project.ipynb --to html \
  --TagRemovePreprocessor.enabled=True \
  --TagRemovePreprocessor.remove_single_output_tags='["remove_single_output"]'
InĀ [Ā ]:
!jupyter nbconvert final_project.ipynb --to html --TagRemovePreprocessor.enabled=True \
--TagRemovePreprocessor.remove_input_tags='["remove_input"]' \
--TagRemovePreprocessor.remove_single_output_tags='["remove_single_output"]'
InĀ [Ā ]: